{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "6852477e-c0fe-4fb0-8958-035333f061f9",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Building prefix dict from the default dictionary ...\n",
      "Loading model from cache C:\\Users\\17828\\AppData\\Local\\Temp\\jieba.cache\n",
      "Loading model cost 3.478 seconds.\n",
      "Prefix dict has been built successfully.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "开始简化的LightGBM参数搜索...\n",
      "Fitting 3 folds for each of 20 candidates, totalling 60 fits\n",
      "参数搜索完成!\n",
      "最佳参数组合:  {'subsample': 0.8, 'reg_lambda': 1, 'reg_alpha': 0.1, 'num_leaves': 127, 'n_estimators': 100, 'min_child_samples': 20, 'max_depth': 10, 'learning_rate': 0.05, 'colsample_bytree': 0.9}\n",
      "最佳准确率:  0.5346696781479391\n",
      "\n",
      "简化的LightGBM分类报告：\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.80      0.51      0.62        79\n",
      "           1       0.51      0.93      0.66        67\n",
      "           2       0.67      0.07      0.13        28\n",
      "\n",
      "    accuracy                           0.60       174\n",
      "   macro avg       0.66      0.50      0.47       174\n",
      "weighted avg       0.67      0.60      0.56       174\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\17828\\AppData\\Roaming\\Python\\Python312\\site-packages\\sklearn\\utils\\validation.py:2739: UserWarning: X does not have valid feature names, but LGBMClassifier was fitted with feature names\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "import lightgbm as lgb\n",
    "# -*- coding: utf-8 -*-\n",
    "import jieba\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import classification_report, confusion_matrix\n",
    "import seaborn as sns\n",
    "import xgboost as xgb\n",
    "from xgboost import XGBClassifier\n",
    "from sklearn.model_selection import RandomizedSearchCV\n",
    "\n",
    "import numpy as np# 1. 数据预处理\n",
    "import pandas as pd \n",
    "def preprocess_text(text):\n",
    "    # 加载停用词表（需准备中文停用词文件）\n",
    "    with open('chinese_stopwords.txt', encoding='utf-8') as f:\n",
    "        stopwords = set(f.read().split())\n",
    "    \n",
    "    words = jieba.cut(text)\n",
    "    return ' '.join([word for word in words if word not in stopwords and len(word) > 1])\n",
    "\n",
    "# 加载数据\n",
    "df = pd.read_csv('final_labeled_comments.csv')\n",
    "df['processed_text'] = df['text'].astype(str).apply(preprocess_text)\n",
    "\n",
    "# 2. 文本分类（情感分析）\n",
    "# 标签编码\n",
    "label_map = {'positive': 0, 'neutral': 1, 'negative': 2}\n",
    "df['label'] = df['最终情感标签'].map(label_map)\n",
    "\n",
    "# TF-IDF向量化\n",
    "tfidf = TfidfVectorizer(max_features=2000)\n",
    "X = tfidf.fit_transform(df['processed_text'])\n",
    "y = df['label']\n",
    "\n",
    "# 拆分数据集\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "# 简化参数搜索\n",
    "def tune_lightgbm_simplified(X_train, y_train):\n",
    "    # 定义参数分布\n",
    "    param_dist = {\n",
    "        'num_leaves': [31, 63, 127],\n",
    "        'max_depth': [5, 10, -1],  # -1表示无限制\n",
    "        'learning_rate': [0.05, 0.1],\n",
    "        'n_estimators': [100, 200],\n",
    "        'min_child_samples': [20, 50],\n",
    "        'subsample': [0.8, 0.9],\n",
    "        'colsample_bytree': [0.8, 0.9],\n",
    "        'reg_alpha': [0, 0.1],\n",
    "        'reg_lambda': [0.1, 1],\n",
    "    }\n",
    "    \n",
    "    # 创建LightGBM分类器\n",
    "    lgb_clf = lgb.LGBMClassifier(\n",
    "        objective='multiclass',\n",
    "        metric='multi_logloss',\n",
    "        num_class=3,\n",
    "        random_state=42,\n",
    "        n_jobs=-1,\n",
    "        verbose=-1  # 减少输出\n",
    "    )\n",
    "    \n",
    "    # 随机搜索\n",
    "    random_search = RandomizedSearchCV(\n",
    "        estimator=lgb_clf,\n",
    "        param_distributions=param_dist,\n",
    "        n_iter=20,  # 减少迭代次数\n",
    "        cv=3,       # 减少交叉验证折数\n",
    "        scoring='accuracy',\n",
    "        n_jobs=-1,\n",
    "        verbose=1,\n",
    "        random_state=42\n",
    "    )\n",
    "    \n",
    "    print(\"开始简化的LightGBM参数搜索...\")\n",
    "    random_search.fit(X_train, y_train)\n",
    "    print(\"参数搜索完成!\")\n",
    "    \n",
    "    # 输出最佳参数\n",
    "    print(\"最佳参数组合: \", random_search.best_params_)\n",
    "    print(\"最佳准确率: \", random_search.best_score_)\n",
    "    \n",
    "    return random_search.best_estimator_\n",
    "\n",
    "# 调优LightGBM\n",
    "best_lgb = tune_lightgbm_simplified(X_train, y_train)\n",
    "\n",
    "# 评估最佳模型\n",
    "y_pred_lgb = best_lgb.predict(X_test)\n",
    "print(\"\\n简化的LightGBM分类报告：\")\n",
    "print(classification_report(y_test, y_pred_lgb))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "51df5c2b-dddb-4dfb-ad4f-1bec818a16c5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "开始随机森林参数搜索...\n",
      "Fitting 5 folds for each of 50 candidates, totalling 250 fits\n",
      "参数搜索完成!\n",
      "最佳参数组合:  {'n_estimators': 300, 'min_samples_split': 5, 'min_samples_leaf': 1, 'max_features': 'log2', 'max_depth': 50, 'bootstrap': False}\n",
      "最佳准确率:  0.6994891043686791\n",
      "\n",
      "随机森林分类报告：\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.79      0.61      0.69        79\n",
      "           1       0.55      0.85      0.67        67\n",
      "           2       0.56      0.18      0.27        28\n",
      "\n",
      "    accuracy                           0.63       174\n",
      "   macro avg       0.63      0.55      0.54       174\n",
      "weighted avg       0.66      0.63      0.61       174\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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cnJyFB8fr8zMTMfx888/y263O7ZoKV26tM6ePavs7GwZhqGQkBDNnTtXGRkZ2rp1q6RrF05cvnzZcVy9etWRzl1Px44dtXTpUr300kvas2ePLl26pJycHD377LN66KGHdOnSJV25coUmD0CxxtQtAJft2rVLXbt21c8//ywPDw+tWrXKkcS9/fbb8vDw0LZt29SgQQPVq1dPERERjteeO3dOM2fO1J133qlNmzZp6dKlmj59ukaOHKkHH3zQaePlX6drfx3bw8NDFStWlCQdPXpUFy5cUGxsrIYMGeJYl3fs2DEFBATkq9lut+e7ava9995TTEyMgoKC5OPjozp16lw3Ufz19YZhcOUtgGKJRA+Ay/72t79p4MCBql+/viSpW7dujk2SBw0aJEnKyMjQsmXLtGLFCrVu3drx2hUrVsjHx0fdu3fXlClTtHPnTg0bNkyStHnzZiUlJTmOzZs3/24NMTExKlGihFavXq3evXsrLy9P0rU1ete7Avh6Ddq2bdtUv359ff755woICJC3t7dsNptsNpv++c9/6uuvv3Y89vPzy7evHgAUFyR6AFzy3nvvKS4uTv/5z38kyTElmpeXp6+//tqR3j3yyCNq1KiRJOmDDz5QlSpV1Lx5c3366adq3bq1AgICHMnbr+vnGjVq5HT17u9NtyYkJGju3Lnq3bu3evbsqbZt2yooKEj33HOPS+8hOztbkjR//nzHucOHD8vX19exwfO4ceOUkJCgJUuWSJIyMzNVokQJl8YHgKKGRg/ADR06dEgjRozQhAkTFBISory8PK1atUoHDx5UlSpV5Ofnpw8++EA2m02XLl2SdG36ddq0aerevbvKly+vb775Jt+avV8buri4OKftWA4cOKC6des6PTcpKUmdOnWSn5+fXnvtNYWEhGjWrFkaM2aM/P39Hfvo/VZubq7S09MVFhamoKAgpwszfvW/V9T6+/vLx8fHMVUMAMUZU7cAbqhEiRJq3769hg8fLulaMnb48GE1btxYH330kY4cOaKoqCjdc889mjVrlsqVK6fg4GBdunRJffr00bRp02QYhuMetb/6dTPk34qNjdWAAQMkybFRcWZmppo3b66EhAStWLHCsS/eM888o3379iksLEzp6em66667nI67775b9957r7Zs2eKo+0by8vKUlZV18x8WABQhbK8C4KZcvHhRZcuW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",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "特征重要性分析...\n",
      "\n",
      "最重要的20个特征：\n",
      "     feature  importance\n",
      "47       nan    0.031186\n",
      "966       奶茶    0.028107\n",
      "1094      好喝    0.025008\n",
      "245       不错    0.013780\n",
      "784      哈哈哈    0.011443\n",
      "267       中午    0.009761\n",
      "137      七不喝    0.009359\n",
      "431       健康    0.008207\n",
      "2254   转发 微博    0.007444\n",
      "1859      生活    0.007326\n",
      "1792      爱喝    0.007213\n",
      "971   奶茶 七不喝    0.006864\n",
      "1288      微博    0.006595\n",
      "1314      快乐    0.006318\n",
      "2253      转发    0.006286\n",
      "2024      经常    0.005934\n",
      "3        111    0.005927\n",
      "2007      红包    0.005733\n",
      "363      从来不    0.005658\n",
      "65        一周    0.005467\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 1000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import jieba\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from matplotlib import rcParams\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "from sklearn.model_selection import train_test_split, RandomizedSearchCV\n",
    "from sklearn.metrics import classification_report, confusion_matrix\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "import seaborn as sns\n",
    "\n",
    "# 设置Matplotlib支持中文字体显示（以SimHei为例，需确保系统中安装了该字体）\n",
    "rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签\n",
    "rcParams['axes.unicode_minus'] = False  # 用来正常显示负号\n",
    "\n",
    "# 1. 数据预处理\n",
    "def preprocess_text(text):\n",
    "    # 加载停用词表（需准备中文停用词文件）\n",
    "    with open('chinese_stopwords.txt', encoding='utf-8') as f:\n",
    "        stopwords = set(f.read().split())\n",
    "    \n",
    "    words = jieba.cut(text)\n",
    "    return ' '.join([word for word in words if word not in stopwords and len(word) > 1])\n",
    "\n",
    "# 加载数据\n",
    "df = pd.read_csv('final_labeled_comments.csv')\n",
    "df['processed_text'] = df['text'].astype(str).apply(preprocess_text)\n",
    "\n",
    "# 2. 文本分类（情感分析）\n",
    "# 标签编码\n",
    "label_map = {'positive': 0, 'neutral': 1, 'negative': 2}\n",
    "df['label'] = df['最终情感标签'].map(label_map)\n",
    "\n",
    "# TF-IDF向量化\n",
    "tfidf = TfidfVectorizer(max_features=5000, ngram_range=(1, 2))\n",
    "X = tfidf.fit_transform(df['processed_text'])\n",
    "y = df['label']\n",
    "\n",
    "# 拆分数据集\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
    "\n",
    "# 3. 定义随机森林分类器\n",
    "rf_clf = RandomForestClassifier(class_weight='balanced', random_state=42, n_jobs=-1)\n",
    "\n",
    "# 4. 定义参数分布\n",
    "param_dist = {\n",
    "    'n_estimators': [100, 200, 300, 400, 500],\n",
    "    'max_depth': [None, 10, 20, 30, 40, 50],\n",
    "    'min_samples_split': [2, 5, 10, 20],\n",
    "    'min_samples_leaf': [1, 2, 4, 8],\n",
    "    'max_features': ['sqrt', 'log2', None],\n",
    "    'bootstrap': [True, False]\n",
    "}\n",
    "\n",
    "# 5. 随机搜索\n",
    "random_search = RandomizedSearchCV(\n",
    "    estimator=rf_clf,\n",
    "    param_distributions=param_dist,\n",
    "    n_iter=50,  # 随机搜索的迭代次数\n",
    "    cv=5,       # 交叉验证的折数\n",
    "    scoring='accuracy',\n",
    "    n_jobs=-1,\n",
    "    verbose=1,\n",
    "    random_state=42\n",
    ")\n",
    "\n",
    "print(\"开始随机森林参数搜索...\")\n",
    "random_search.fit(X_train, y_train)\n",
    "print(\"参数搜索完成!\")\n",
    "\n",
    "# 6. 输出最佳参数\n",
    "print(\"最佳参数组合: \", random_search.best_params_)\n",
    "print(\"最佳准确率: \", random_search.best_score_)\n",
    "\n",
    "# 7. 评估最佳模型\n",
    "best_rf = random_search.best_estimator_\n",
    "y_pred_rf = best_rf.predict(X_test)\n",
    "print(\"\\n随机森林分类报告：\")\n",
    "print(classification_report(y_test, y_pred_rf))\n",
    "\n",
    "# 8. 混淆矩阵可视化\n",
    "def plot_confusion_matrix(y_true, y_pred, classes):\n",
    "    cm = confusion_matrix(y_true, y_pred)\n",
    "    plt.figure(figsize=(8, 6))\n",
    "    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', \n",
    "                xticklabels=classes, yticklabels=classes)\n",
    "    plt.xlabel('预测标签')\n",
    "    plt.ylabel('真实标签')\n",
    "    plt.title('混淆矩阵')\n",
    "    plt.show()\n",
    "\n",
    "# 获取类别名称\n",
    "class_names = {0: 'positive', 1: 'neutral', 2: 'negative'}\n",
    "plot_confusion_matrix(y_test, y_pred_rf, [class_names[i] for i in sorted(class_names.keys())])\n",
    "\n",
    "# 9. 特征重要性分析\n",
    "print(\"\\n特征重要性分析...\")\n",
    "importance = best_rf.feature_importances_\n",
    "feature_names = tfidf.get_feature_names_out()\n",
    "\n",
    "# 创建特征重要性DataFrame\n",
    "feature_importance = pd.DataFrame({\n",
    "    'feature': feature_names,\n",
    "    'importance': importance\n",
    "}).sort_values('importance', ascending=False)\n",
    "\n",
    "# 显示最重要的20个特征\n",
    "print(\"\\n最重要的20个特征：\")\n",
    "print(feature_importance.head(20))\n",
    "\n",
    "# 可视化最重要的20个特征\n",
    "plt.figure(figsize=(10, 6))\n",
    "feature_importance.head(20).plot(kind='barh', x='feature', y='importance', color='skyblue')\n",
    "plt.title('最重要的20个特征')\n",
    "plt.xlabel('重要性得分')\n",
    "plt.ylabel('特征词')\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "52f0ffb3-22e6-41ea-9aa2-1f0499ce65ce",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 01\n",
      "\tTrain Loss: 1.033 | Train Acc: 48.72%\n",
      "\t Val. Loss: 1.012 |  Val. Acc: 48.03%\n",
      "Epoch: 02\n",
      "\tTrain Loss: 1.010 | Train Acc: 48.45%\n",
      "\t Val. Loss: 1.012 |  Val. Acc: 48.03%\n",
      "Epoch: 03\n",
      "\tTrain Loss: 1.007 | Train Acc: 48.09%\n",
      "\t Val. Loss: 1.010 |  Val. Acc: 48.03%\n",
      "Epoch: 04\n",
      "\tTrain Loss: 1.007 | Train Acc: 48.58%\n",
      "\t Val. Loss: 1.010 |  Val. Acc: 48.03%\n",
      "Epoch: 05\n",
      "\tTrain Loss: 1.004 | Train Acc: 48.61%\n",
      "\t Val. Loss: 1.010 |  Val. Acc: 48.03%\n",
      "Epoch: 06\n",
      "\tTrain Loss: 1.001 | Train Acc: 48.33%\n",
      "\t Val. Loss: 1.011 |  Val. Acc: 48.03%\n",
      "Epoch: 07\n",
      "\tTrain Loss: 1.006 | Train Acc: 48.65%\n",
      "\t Val. Loss: 1.010 |  Val. Acc: 48.03%\n",
      "Epoch: 08\n",
      "\tTrain Loss: 1.002 | Train Acc: 48.45%\n",
      "\t Val. Loss: 1.010 |  Val. Acc: 48.03%\n",
      "Epoch: 09\n",
      "\tTrain Loss: 1.007 | Train Acc: 48.25%\n",
      "\t Val. Loss: 1.011 |  Val. Acc: 48.03%\n",
      "Epoch: 10\n",
      "\tTrain Loss: 1.005 | Train Acc: 48.35%\n",
      "\t Val. Loss: 1.010 |  Val. Acc: 48.03%\n",
      "\n",
      "LSTM模型分类报告：\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "    positive       0.48      1.00      0.65        84\n",
      "     neutral       0.00      0.00      0.00        64\n",
      "    negative       0.00      0.00      0.00        26\n",
      "\n",
      "    accuracy                           0.48       174\n",
      "   macro avg       0.16      0.33      0.22       174\n",
      "weighted avg       0.23      0.48      0.31       174\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\17828\\AppData\\Roaming\\Python\\Python312\\site-packages\\sklearn\\metrics\\_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
      "  _warn_prf(average, modifier, f\"{metric.capitalize()} is\", len(result))\n",
      "C:\\Users\\17828\\AppData\\Roaming\\Python\\Python312\\site-packages\\sklearn\\metrics\\_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
      "  _warn_prf(average, modifier, f\"{metric.capitalize()} is\", len(result))\n",
      "C:\\Users\\17828\\AppData\\Roaming\\Python\\Python312\\site-packages\\sklearn\\metrics\\_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
      "  _warn_prf(average, modifier, f\"{metric.capitalize()} is\", len(result))\n"
     ]
    },
    {
     "data": {
      "image/png": "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MZeMqaysTN7e3mrSpIlefvllDRo0SJJ04MABLVmyRM8++6zmz5+vyMhISdK7774rLy+GLQNwL/xWA3DFysrKZLFY9Mknn+jRRx9VcXGxpAsTH2rVqqVTp05pzZo12rx5s3r16qX8/HxlZ2dr8uTJeuKJJ2wTNgICAhQcHPy7P2vAgAF66623ZLVa1bNnTyUmJuqxxx5TUFCQatWqpaCgINWoUUO1atVSjRo11LBhQ0lS7dq1bUleYWGh/vnPf2rKlCn6z3/+o6lTp+qll17SuXPn1KVLFxI9AG6H32oArtjWrVsVGRmpFi1a6PXXX1dMTIwsFott3J4kdevWTQcOHJB0oVJ34403auPGjQoMDLQlVoZhqEqVKpf9ed98843y8vL03nvvaciQIdqyZYtyc3N1+vRpxcXF6YknntDp06eVl5dni8EwDKWlpenFF19U06ZNlZWVpa1bt+qBBx7Qhg0b5O/vr+joaI0fP15r165Vdna2C74pADAHiR6AK9auXTvt27dPy5YtU9OmTbVkyRJFRESoUaNGtnOKiorUpEkTu+uuu+46jRs3ThaLReXl5Tp9+rRq1qwpSb+7nMrrr7+uJk2a6IEHHtCmTZuUnJyszz//3C6x3Lt3r62rWJISExN166236tixY3riiSe0aNEiNWvWTLVq1VJYWJgmT56siIgItWnTRq+99poeeeQRsRgBAHfBGD0A10y9evX0+eefKz8/X5KUm5srf39/Va1aVZJ9EvfQQw9p5MiROn/+vPbv36/69etLkoqLiy+5ft7y5cu1ZcsWjRgxQpK0aNEi3XzzzWrSpIltbKAkLVmyRHPmzFF6eroCAwM1ZswYDR8+XEFBQSouLtakSZN0+PBhHTx4UJ07d5Ykvf3227r99ts1YMAA1305AGACKnoArpkaNWooMjLSNhM2NTVVERERts+LiookSWlpadq5c6f69Omj3bt3a+XKlWrbtq26deumOXPmqLS01Dbe7xdz5szRf/7zH9uaeZ07d9aaNWtUr1499ezZ03beM888o4CAAE2dOlWS5Ofnp6CgIP3000+KjIxUSUmJjh8/rmeffVbShYkgY8eOVUlJieu+GAAwCYkegGsuKipK//znPzVnzhz16NFDS5Ys0VNPPaXHHntMkjRt2jSNHTtWQUFBCggI0EcffaTq1avrtttuU0FBgR588EG98sordm0uWbJE9957r22/tLRUL774op5++mnbGnqS5Ovrq4kTJ2r27NnKzc21Ha9Tp44iIyP16aefqkOHDtqzZ4/y8/P18ccfq0+fPhd1LwOAOyDRA3BVcnNzdeTIEbv154KCgrRkyRJt3bpVY8eO1WeffaaHH35YxcXFWrlypZYtW6axY8dKksaPH69evXpp7NixuvPOOzV06FAFBwerfv36tgqgJFv7JSUlKisrU1FRkQYOHKh+/fpp6dKl2rBhg21Cx8MPP6z09HQFBQVJ+r8u44kTJ6pFixby9vbW119/LX9/f82dO1fDhg2TdCF5BAB3whg9AFfl1Vdf1fz5821doT/++KOGDRumunXrauPGjQoJCdGCBQv01ltv6dZbb9X8+fM1YcIE1axZUwsWLNDXX3+tH3/8UdKFV54NGTJEubm5SkxM1PTp0zVjxgy7n2e1WlVSUqJq1aopPj5ekjRjxgwFBwdr4MCBki4kheHh4bZr/Pz8VK1atUsuhlxUVKT+/fvLarXKarXq9OnTl13qBQAqC951C+CaKi8vV0pKijp27HjRZ0ePHlWDBg1s+4Zh6MSJEwoLC7vo3FOnTslqtdrN4AUAOIdEDwAAwE0xRg8AAMBNkegBAAC4KRI9AAAAN0WiBwAA4KZI9AAAANwUiR4AAICbItEDAABwUyR6AAAAbur/AXGRIv3pdFd+AAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "from torch.utils.data import Dataset, DataLoader\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import jieba\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import classification_report, confusion_matrix\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from collections import Counter\n",
    "\n",
    "# 设置Matplotlib支持中文字体显示\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "plt.rcParams['axes.unicode_minus'] = False\n",
    "\n",
    "# 1. 数据预处理\n",
    "def preprocess_text(text):\n",
    "    # 加载停用词表（需准备中文停用词文件）\n",
    "    with open('chinese_stopwords.txt', encoding='utf-8') as f:\n",
    "        stopwords = set(f.read().split())\n",
    "    \n",
    "    words = jieba.cut(text)\n",
    "    return ' '.join([word for word in words if word not in stopwords and len(word) > 1])\n",
    "\n",
    "# 加载数据\n",
    "df = pd.read_csv('final_labeled_comments.csv')\n",
    "df['processed_text'] = df['text'].astype(str).apply(preprocess_text)\n",
    "\n",
    "# 标签编码\n",
    "label_map = {'positive': 0, 'neutral': 1, 'negative': 2}\n",
    "df['label'] = df['最终情感标签'].map(label_map)\n",
    "\n",
    "# 2. 创建词汇表\n",
    "texts = df['processed_text'].tolist()\n",
    "words = ' '.join(texts).split()\n",
    "word_counts = Counter(words)\n",
    "vocab = {'<PAD>': 0, '<UNK>': 1}\n",
    "vocab.update({word: i+2 for i, (word, _) in enumerate(word_counts.most_common(10000))})\n",
    "\n",
    "# 3. 定义数据集类\n",
    "class TextDataset(Dataset):\n",
    "    def __init__(self, texts, labels, vocab, max_len=128):\n",
    "        self.texts = texts\n",
    "        self.labels = labels\n",
    "        self.vocab = vocab\n",
    "        self.max_len = max_len\n",
    "    \n",
    "    def __len__(self):\n",
    "        return len(self.texts)\n",
    "    \n",
    "    def __getitem__(self, idx):\n",
    "        text = self.texts[idx]\n",
    "        label = self.labels[idx]\n",
    "        \n",
    "        # 将文本转换为词索引序列\n",
    "        words = text.split()\n",
    "        indices = [self.vocab.get(word, self.vocab['<UNK>']) for word in words]\n",
    "        \n",
    "        # 填充或截断到固定长度\n",
    "        if len(indices) < self.max_len:\n",
    "            indices = indices + [self.vocab['<PAD>']] * (self.max_len - len(indices))\n",
    "        else:\n",
    "            indices = indices[:self.max_len]\n",
    "        \n",
    "        return torch.LongTensor(indices), torch.LongTensor([label])\n",
    "\n",
    "# 4. 划分数据集\n",
    "train_texts, val_texts, train_labels, val_labels = train_test_split(\n",
    "    df['processed_text'], df['label'], test_size=0.2, random_state=42, stratify=df['label']\n",
    ")\n",
    "\n",
    "# 创建数据集和数据加载器\n",
    "train_dataset = TextDataset(train_texts.tolist(), train_labels.tolist(), vocab)\n",
    "val_dataset = TextDataset(val_texts.tolist(), val_labels.tolist(), vocab)\n",
    "\n",
    "batch_size = 64\n",
    "train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\n",
    "val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)\n",
    "\n",
    "# 5. 定义LSTM模型\n",
    "class LSTMClassifier(nn.Module):\n",
    "    def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim, n_layers, dropout):\n",
    "        super().__init__()\n",
    "        self.embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=0)\n",
    "        self.lstm = nn.LSTM(embedding_dim, hidden_dim, num_layers=n_layers, \n",
    "                            dropout=dropout, batch_first=True)\n",
    "        self.fc = nn.Linear(hidden_dim, output_dim)\n",
    "        self.dropout = nn.Dropout(dropout)\n",
    "    \n",
    "    def forward(self, text):\n",
    "        # text shape: [batch_size, seq_len]\n",
    "        embedded = self.dropout(self.embedding(text))\n",
    "        # embedded shape: [batch_size, seq_len, embedding_dim]\n",
    "        \n",
    "        output, (hidden, cell) = self.lstm(embedded)\n",
    "        # output shape: [batch_size, seq_len, hidden_dim]\n",
    "        # hidden shape: [num_layers, batch_size, hidden_dim]\n",
    "        \n",
    "        # 使用最后一个时间步的输出\n",
    "        hidden = self.dropout(hidden[-1])\n",
    "        # hidden shape: [batch_size, hidden_dim]\n",
    "        \n",
    "        return self.fc(hidden)\n",
    "\n",
    "# 模型参数\n",
    "vocab_size = len(vocab)\n",
    "embedding_dim = 128\n",
    "hidden_dim = 256\n",
    "output_dim = 3  # 三分类问题\n",
    "n_layers = 2\n",
    "dropout = 0.5\n",
    "\n",
    "model = LSTMClassifier(vocab_size, embedding_dim, hidden_dim, output_dim, n_layers, dropout)\n",
    "\n",
    "# 6. 定义优化器和损失函数\n",
    "optimizer = optim.Adam(model.parameters())\n",
    "criterion = nn.CrossEntropyLoss()\n",
    "\n",
    "# 将模型移动到GPU（如果可用）\n",
    "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
    "model = model.to(device)\n",
    "\n",
    "# 7. 训练函数\n",
    "def train(model, iterator, optimizer, criterion):\n",
    "    model.train()\n",
    "    epoch_loss = 0\n",
    "    epoch_acc = 0\n",
    "    \n",
    "    for batch in iterator:\n",
    "        text, labels = batch\n",
    "        text = text.to(device)\n",
    "        labels = labels.squeeze(1).to(device)\n",
    "        \n",
    "        optimizer.zero_grad()\n",
    "        predictions = model(text)\n",
    "        \n",
    "        loss = criterion(predictions, labels)\n",
    "        acc = (predictions.argmax(1) == labels).sum().item() / labels.shape[0]\n",
    "        \n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        \n",
    "        epoch_loss += loss.item()\n",
    "        epoch_acc += acc\n",
    "    \n",
    "    return epoch_loss / len(iterator), epoch_acc / len(iterator)\n",
    "\n",
    "# 8. 评估函数\n",
    "def evaluate(model, iterator, criterion):\n",
    "    model.eval()\n",
    "    epoch_loss = 0\n",
    "    epoch_acc = 0\n",
    "    \n",
    "    with torch.no_grad():\n",
    "        for batch in iterator:\n",
    "            text, labels = batch\n",
    "            text = text.to(device)\n",
    "            labels = labels.squeeze(1).to(device)\n",
    "            \n",
    "            predictions = model(text)\n",
    "            \n",
    "            loss = criterion(predictions, labels)\n",
    "            acc = (predictions.argmax(1) == labels).sum().item() / labels.shape[0]\n",
    "            \n",
    "            epoch_loss += loss.item()\n",
    "            epoch_acc += acc\n",
    "    \n",
    "    return epoch_loss / len(iterator), epoch_acc / len(iterator)\n",
    "\n",
    "# 9. 训练模型\n",
    "N_EPOCHS = 10\n",
    "\n",
    "for epoch in range(N_EPOCHS):\n",
    "    train_loss, train_acc = train(model, train_loader, optimizer, criterion)\n",
    "    valid_loss, valid_acc = evaluate(model, val_loader, criterion)\n",
    "    \n",
    "    print(f'Epoch: {epoch+1:02}')\n",
    "    print(f'\\tTrain Loss: {train_loss:.3f} | Train Acc: {train_acc*100:.2f}%')\n",
    "    print(f'\\t Val. Loss: {valid_loss:.3f} |  Val. Acc: {valid_acc*100:.2f}%')\n",
    "\n",
    "# 10. 预测并生成分类报告\n",
    "def predict_sentiment(model, sentence, vocab, max_len=128):\n",
    "    model.eval()\n",
    "    tokenized = [vocab.get(word, vocab['<UNK>']) for word in preprocess_text(sentence).split()]\n",
    "    if len(tokenized) < max_len:\n",
    "        tokenized = tokenized + [vocab['<PAD>']] * (max_len - len(tokenized))\n",
    "    else:\n",
    "        tokenized = tokenized[:max_len]\n",
    "    \n",
    "    tensor = torch.LongTensor(tokenized).unsqueeze(0).to(device)\n",
    "    prediction = torch.sigmoid(model(tensor))\n",
    "    predicted_class = torch.argmax(prediction, dim=1).item()\n",
    "    \n",
    "    return predicted_class\n",
    "\n",
    "# 在验证集上生成预测\n",
    "all_preds = []\n",
    "all_labels = []\n",
    "\n",
    "with torch.no_grad():\n",
    "    for batch in val_loader:\n",
    "        text, labels = batch\n",
    "        text = text.to(device)\n",
    "        labels = labels.squeeze(1).to(device)\n",
    "        \n",
    "        predictions = model(text)\n",
    "        preds = predictions.argmax(1)\n",
    "        \n",
    "        all_preds.extend(preds.cpu().numpy())\n",
    "        all_labels.extend(labels.cpu().numpy())\n",
    "\n",
    "print(\"\\nLSTM模型分类报告：\")\n",
    "print(classification_report(all_labels, all_preds, target_names=['positive', 'neutral', 'negative']))\n",
    "\n",
    "# 11. 混淆矩阵可视化\n",
    "def plot_confusion_matrix(y_true, y_pred, classes):\n",
    "    cm = confusion_matrix(y_true, y_pred)\n",
    "    plt.figure(figsize=(8, 6))\n",
    "    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', \n",
    "                xticklabels=classes, yticklabels=classes)\n",
    "    plt.xlabel('预测标签')\n",
    "    plt.ylabel('真实标签')\n",
    "    plt.title('混淆矩阵')\n",
    "    plt.show()\n",
    "\n",
    "plot_confusion_matrix(all_labels, all_preds, ['positive', 'neutral', 'negative'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e89def40-1359-410b-a5e4-28d92ce5b62d",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "23d2cfa3-3ce8-49bd-88c5-8c52c2cb8d88",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "2202dd47-65c7-4250-b0f6-00844bf30033",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "训练模型: tfidf_rf\n",
      "Fitting 5 folds for each of 10 candidates, totalling 50 fits\n",
      "tfidf_rf 最佳参数: {'tfidf__max_features': 3000, 'rf__n_estimators': 100, 'rf__min_samples_split': 2, 'rf__min_samples_leaf': 1, 'rf__max_features': 'sqrt', 'rf__max_depth': None}\n",
      "tfidf_rf 测试集F1分数: 0.6744\n",
      "\n",
      "训练模型: count_rf\n",
      "Fitting 5 folds for each of 10 candidates, totalling 50 fits\n",
      "训练 count_rf 模型时出错: Invalid parameter 'tfidf' for estimator Pipeline(steps=[('count',\n",
      "                 CountVectorizer(max_features=5000, ngram_range=(1, 2))),\n",
      "                ('rf',\n",
      "                 RandomForestClassifier(class_weight='balanced', n_jobs=-1,\n",
      "                                        random_state=42))]). Valid parameters are: ['memory', 'steps', 'transform_input', 'verbose'].\n",
      "\n",
      "训练模型: tfidf_svm\n",
      "Fitting 5 folds for each of 10 candidates, totalling 50 fits\n",
      "tfidf_svm 最佳参数: {'tfidf__max_features': 5000, 'svm__kernel': 'linear', 'svm__gamma': 'auto', 'svm__C': 1}\n",
      "tfidf_svm 测试集F1分数: 0.6856\n",
      "\n",
      "训练模型: tfidf_lr\n",
      "Fitting 5 folds for each of 8 candidates, totalling 40 fits\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\17828\\AppData\\Roaming\\Python\\Python312\\site-packages\\sklearn\\model_selection\\_search.py:317: UserWarning: The total space of parameters 8 is smaller than n_iter=10. Running 8 iterations. For exhaustive searches, use GridSearchCV.\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tfidf_lr 最佳参数: {'tfidf__max_features': 3000, 'lr__solver': 'liblinear', 'lr__penalty': 'l2', 'lr__C': 1}\n",
      "tfidf_lr 测试集F1分数: 0.6809\n",
      "\n",
      "训练模型: tfidf_nb\n",
      "Fitting 5 folds for each of 6 candidates, totalling 30 fits\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\17828\\AppData\\Roaming\\Python\\Python312\\site-packages\\sklearn\\model_selection\\_search.py:317: UserWarning: The total space of parameters 6 is smaller than n_iter=10. Running 6 iterations. For exhaustive searches, use GridSearchCV.\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tfidf_nb 最佳参数: {'tfidf__max_features': 3000, 'nb__alpha': 0.1}\n",
      "tfidf_nb 测试集F1分数: 0.5857\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\17828\\AppData\\Local\\Temp\\ipykernel_5172\\769557366.py:149: FutureWarning: \n",
      "\n",
      "Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `y` variable to `hue` and set `legend=False` for the same effect.\n",
      "\n",
      "  sns.barplot(x=f1_scores, y=model_names, palette='viridis')\n"
     ]
    },
    {
     "data": {
      "image/png": "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+/THH38oOTlZV155pfr371/eU4WBnNEG/Ju3gtSsWbPYjQ0yMjLk7u5+1m2OHTtW6vUBqWz72mmzZ8/W+vXrtXXr1nKaHS4lZdnXnn76aT3yyCO66qqrynl2uJSUZV87ePCgbrnlFsf/UapevboaN26sv/76q1zniotbWfa1//znPxo8eLCaNm0qSZoyZYr8/Px0/Phx+fv7l+d0YRhntAFH/ipI27ZttWnTJsf7vXv3KicnRzVr1iz1Nlu3blVwcHC5zhMXv7Lsa5IUHx+vp59+WvPnz1dgYGB5TxOXgLLsa/PmzdO7774rf39/+fv7a+PGjerWrZvGjx9fEVPGRaos+1pISIiysrIc7wsLC3Xw4EGuM8VZlWVfy8/P15EjRxzvTz8qqaCgoPwmCiM5ow2Ivwpy4403Ki0tTR9//LEkafz48br11lvl6uqq9PR05eXlFdvmrrvu0saNGxUXF6f8/HxNnDhRXbp0qeip4yJTln3tyJEj6t69u4YPH642bdroxIkTOnHiREVPHReZsuxrf/31l7Zt26atW7dq69atuuaaazRz5kxFRUVV9PRxESnLvnb//fdr8eLF+vzzz3Xw4EGNHDlSOTk5ioiIqOjp4yJSln0tIiJCH3zwgWbMmKHY2Fg98MADuv766xUQEFDR08clolzb4PxvSoqyWrRokeXl5WXVrl3bCggIsH777TfLsiyrQYMG1qJFi0rcZtq0aZbdbrcuu+wyq0GDBtbhw4crcMa4WJ3vvjZ58mRLUrEXcC5l+efa391000086gGlUpZ9bcmSJdZVV11leXp6WldccYW1cePGCpwxLlbnu69lZWVZQ4YMsYKCgix3d3frpptusnbt2lXBs8bFTP941EN5toHt/38hKsihQ4e0efNmtW/fXrVq1SrVNrt27dL27dt10003ydfXt5xniEtFWfY1oCzY11BR2NdQUdjXUJVdSBsQfwAAAABgAK75AwAAAAADEH8AAAAAYADiDwAAAAAMQPwBAAAAgAGIPwAAAAAwAPEHAMAlJCMjQ8ePH6/saQAAqiDiDwCAM5g8ebI+++yzUq+/YsUKNW/evBxnVFxhYaHatWun7777TpL0zDPPKDo6usR1T5w4oddff12WZalTp05auHChli9frq+//lq5ublq0aKFDh06VJHTBwBUILfKngAAAFXVxo0bdd1115V6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",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "最佳模型: tfidf_svm\n",
      "最佳F1分数: 0.6856\n",
      "最佳参数: {'tfidf__max_features': 5000, 'svm__kernel': 'linear', 'svm__gamma': 'auto', 'svm__C': 1}\n"
     ]
    }
   ],
   "source": [
    "import jieba\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from matplotlib import rcParams\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer\n",
    "from sklearn.model_selection import train_test_split, RandomizedSearchCV\n",
    "from sklearn.metrics import classification_report, confusion_matrix, f1_score\n",
    "from sklearn.ensemble import RandomForestClassifier, VotingClassifier\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.naive_bayes import MultinomialNB\n",
    "from sklearn.pipeline import Pipeline  # 添加这行导入语句\n",
    "import seaborn as sns\n",
    "import re\n",
    "from zhconv import convert\n",
    "\n",
    "# 设置Matplotlib支持中文字体显示\n",
    "rcParams['font.sans-serif'] = ['SimHei']\n",
    "rcParams['axes.unicode_minus'] = False\n",
    "\n",
    "# 1. 数据预处理\n",
    "def preprocess_text(text):\n",
    "    # 简繁转换\n",
    "    text = convert(text, 'zh-hans')\n",
    "    # 去除特殊字符和数字\n",
    "    text = re.sub(r'[^\\w\\s]', '', text)\n",
    "    text = re.sub(r'\\d+', '', text)\n",
    "    # 加载停用词表\n",
    "    with open('chinese_stopwords.txt', encoding='utf-8') as f:\n",
    "        stopwords = set(f.read().split())\n",
    "    # 加载自定义词典（如果有）\n",
    "    # jieba.load_userdict('bubble_tea_terms.txt')\n",
    "    \n",
    "    words = jieba.cut(text)\n",
    "    return ' '.join([word for word in words if word not in stopwords and len(word) > 1])\n",
    "\n",
    "# 加载数据\n",
    "df = pd.read_csv('final_labeled_comments.csv')\n",
    "df['processed_text'] = df['text'].astype(str).apply(preprocess_text)\n",
    "\n",
    "# 2. 文本分类（情感分析）\n",
    "# 标签编码\n",
    "label_map = {'positive': 0, 'neutral': 1, 'negative': 2}\n",
    "df['label'] = df['最终情感标签'].map(label_map)\n",
    "\n",
    "# 3. 定义多个模型管道\n",
    "pipelines = [\n",
    "    ('tfidf_rf', Pipeline([\n",
    "        ('tfidf', TfidfVectorizer(max_features=5000, ngram_range=(1, 2))),\n",
    "        ('rf', RandomForestClassifier(class_weight='balanced', random_state=42, n_jobs=-1))\n",
    "    ])),\n",
    "    ('count_rf', Pipeline([\n",
    "        ('count', CountVectorizer(max_features=5000, ngram_range=(1, 2))),\n",
    "        ('rf', RandomForestClassifier(class_weight='balanced', random_state=42, n_jobs=-1))\n",
    "    ])),\n",
    "    ('tfidf_svm', Pipeline([\n",
    "        ('tfidf', TfidfVectorizer(max_features=5000, ngram_range=(1, 2))),\n",
    "        ('svm', SVC(class_weight='balanced', probability=True, random_state=42))\n",
    "    ])),\n",
    "    ('tfidf_lr', Pipeline([\n",
    "        ('tfidf', TfidfVectorizer(max_features=5000, ngram_range=(1, 2))),\n",
    "        ('lr', LogisticRegression(class_weight='balanced', max_iter=1000, random_state=42))\n",
    "    ])),\n",
    "    ('tfidf_nb', Pipeline([\n",
    "        ('tfidf', TfidfVectorizer(max_features=5000, ngram_range=(1, 2))),\n",
    "        ('nb', MultinomialNB())\n",
    "    ]))\n",
    "]\n",
    "\n",
    "# 4. 数据集拆分\n",
    "X = df['processed_text']\n",
    "y = df['label']\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)\n",
    "\n",
    "# 5. 模型训练与评估\n",
    "results = []\n",
    "model_names = []\n",
    "f1_scores = []\n",
    "\n",
    "for name, pipeline in pipelines:\n",
    "    print(f\"\\n训练模型: {name}\")\n",
    "    \n",
    "    # 简化参数搜索以加快速度\n",
    "    if 'rf' in name:\n",
    "        param_dist = {\n",
    "            'tfidf__max_features': [3000, 5000] if 'tfidf' in name else ['count__max_features', 3000, 5000],\n",
    "            'rf__n_estimators': [100, 200],\n",
    "            'rf__max_depth': [None, 10, 20],\n",
    "            'rf__min_samples_split': [2, 5],\n",
    "            'rf__min_samples_leaf': [1, 2],\n",
    "            'rf__max_features': ['sqrt', 'log2']\n",
    "        }\n",
    "    elif 'svm' in name:\n",
    "        param_dist = {\n",
    "            'tfidf__max_features': [3000, 5000],\n",
    "            'svm__C': [0.1, 1],\n",
    "            'svm__gamma': ['scale', 'auto'],\n",
    "            'svm__kernel': ['linear', 'rbf']\n",
    "        }\n",
    "    elif 'lr' in name:\n",
    "        param_dist = {\n",
    "            'tfidf__max_features': [3000, 5000],\n",
    "            'lr__C': [0.1, 1],\n",
    "            'lr__penalty': ['l1', 'l2'],\n",
    "            'lr__solver': ['liblinear']\n",
    "        }\n",
    "    elif 'nb' in name:\n",
    "        param_dist = {\n",
    "            'tfidf__max_features': [3000, 5000],\n",
    "            'nb__alpha': [0.1, 0.5, 1.0]\n",
    "        }\n",
    "    \n",
    "    random_search = RandomizedSearchCV(\n",
    "        estimator=pipeline,\n",
    "        param_distributions=param_dist,\n",
    "        n_iter=10,\n",
    "        cv=5,\n",
    "        scoring='f1_weighted',\n",
    "        n_jobs=-1,\n",
    "        verbose=1,\n",
    "        random_state=42\n",
    "    )\n",
    "    \n",
    "    try:\n",
    "        random_search.fit(X_train, y_train)\n",
    "        \n",
    "        # 评估模型\n",
    "        y_pred = random_search.predict(X_test)\n",
    "        f1 = f1_score(y_test, y_pred, average='weighted')\n",
    "        \n",
    "        results.append({\n",
    "            'model': name,\n",
    "            'best_params': random_search.best_params_,\n",
    "            'f1_score': f1\n",
    "        })\n",
    "        \n",
    "        model_names.append(name)\n",
    "        f1_scores.append(f1)\n",
    "        \n",
    "        print(f\"{name} 最佳参数: {random_search.best_params_}\")\n",
    "        print(f\"{name} 测试集F1分数: {f1:.4f}\")\n",
    "    except Exception as e:\n",
    "        print(f\"训练 {name} 模型时出错: {e}\")\n",
    "        continue\n",
    "\n",
    "# 6. 可视化比较\n",
    "plt.figure(figsize=(10, 6))\n",
    "sns.barplot(x=f1_scores, y=model_names, palette='viridis')\n",
    "plt.title('不同模型的F1分数比较')\n",
    "plt.xlabel('加权F1分数')\n",
    "plt.ylabel('模型')\n",
    "plt.xlim(0, 1)\n",
    "plt.show()\n",
    "\n",
    "# 7. 选择最佳模型\n",
    "if results:\n",
    "    best_model_info = max(results, key=lambda x: x['f1_score'])\n",
    "    print(f\"\\n最佳模型: {best_model_info['model']}\")\n",
    "    print(f\"最佳F1分数: {best_model_info['f1_score']:.4f}\")\n",
    "    print(f\"最佳参数: {best_model_info['best_params']}\")\n",
    "else:\n",
    "    print(\"没有成功训练任何模型，请检查数据和参数设置\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "b56c9e66-59bc-4de2-b475-d4eb5c4377a3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 01\n",
      "\tTrain Loss: 0.961\n",
      "\t Val. Loss: 0.815 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 02\n",
      "\tTrain Loss: 0.771\n",
      "\t Val. Loss: 0.778 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 03\n",
      "\tTrain Loss: 0.686\n",
      "\t Val. Loss: 0.771 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 04\n",
      "\tTrain Loss: 0.561\n",
      "\t Val. Loss: 0.779 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 05\n",
      "\tTrain Loss: 0.521\n",
      "\t Val. Loss: 0.791 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 06\n",
      "\tTrain Loss: 0.420\n",
      "\t Val. Loss: 0.837 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 07\n",
      "\tTrain Loss: 0.325\n",
      "\t Val. Loss: 0.910 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 08\n",
      "\tTrain Loss: 0.315\n",
      "\t Val. Loss: 0.949 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 09\n",
      "\tTrain Loss: 0.252\n",
      "\t Val. Loss: 1.015 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 10\n",
      "\tTrain Loss: 0.229\n",
      "\t Val. Loss: 1.064 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 11\n",
      "\tTrain Loss: 0.204\n",
      "\t Val. Loss: 1.167 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 12\n",
      "\tTrain Loss: 0.173\n",
      "\t Val. Loss: 1.207 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 13\n",
      "\tTrain Loss: 0.163\n",
      "\t Val. Loss: 1.261 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 14\n",
      "\tTrain Loss: 0.156\n",
      "\t Val. Loss: 1.317 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 15\n",
      "\tTrain Loss: 0.125\n",
      "\t Val. Loss: 1.343 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 16\n",
      "\tTrain Loss: 0.116\n",
      "\t Val. Loss: 1.354 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 17\n",
      "\tTrain Loss: 0.123\n",
      "\t Val. Loss: 1.430 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 18\n",
      "\tTrain Loss: 0.089\n",
      "\t Val. Loss: 1.445 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 19\n",
      "\tTrain Loss: 0.105\n",
      "\t Val. Loss: 1.491 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 20\n",
      "\tTrain Loss: 0.107\n",
      "\t Val. Loss: 1.550 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 21\n",
      "\tTrain Loss: 0.089\n",
      "\t Val. Loss: 1.590 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 22\n",
      "\tTrain Loss: 0.110\n",
      "\t Val. Loss: 1.569 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 23\n",
      "\tTrain Loss: 0.071\n",
      "\t Val. Loss: 1.558 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 24\n",
      "\tTrain Loss: 0.068\n",
      "\t Val. Loss: 1.586 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 25\n",
      "\tTrain Loss: 0.086\n",
      "\t Val. Loss: 1.601 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 26\n",
      "\tTrain Loss: 0.072\n",
      "\t Val. Loss: 1.702 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 27\n",
      "\tTrain Loss: 0.089\n",
      "\t Val. Loss: 1.724 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 28\n",
      "\tTrain Loss: 0.116\n",
      "\t Val. Loss: 1.696 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 29\n",
      "\tTrain Loss: 0.077\n",
      "\t Val. Loss: 1.732 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 30\n",
      "\tTrain Loss: 0.066\n",
      "\t Val. Loss: 1.721 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 31\n",
      "\tTrain Loss: 0.073\n",
      "\t Val. Loss: 1.763 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 32\n",
      "\tTrain Loss: 0.073\n",
      "\t Val. Loss: 1.766 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 33\n",
      "\tTrain Loss: 0.074\n",
      "\t Val. Loss: 1.759 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 34\n",
      "\tTrain Loss: 0.083\n",
      "\t Val. Loss: 1.711 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 35\n",
      "\tTrain Loss: 0.082\n",
      "\t Val. Loss: 1.722 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 36\n",
      "\tTrain Loss: 0.073\n",
      "\t Val. Loss: 1.728 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 37\n",
      "\tTrain Loss: 0.103\n",
      "\t Val. Loss: 1.761 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 38\n",
      "\tTrain Loss: 0.114\n",
      "\t Val. Loss: 1.711 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 39\n",
      "\tTrain Loss: 0.083\n",
      "\t Val. Loss: 1.678 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 40\n",
      "\tTrain Loss: 0.077\n",
      "\t Val. Loss: 1.682 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 41\n",
      "\tTrain Loss: 0.084\n",
      "\t Val. Loss: 1.695 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 42\n",
      "\tTrain Loss: 0.093\n",
      "\t Val. Loss: 1.656 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 43\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.656 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 44\n",
      "\tTrain Loss: 0.066\n",
      "\t Val. Loss: 1.670 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 45\n",
      "\tTrain Loss: 0.065\n",
      "\t Val. Loss: 1.687 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 46\n",
      "\tTrain Loss: 0.051\n",
      "\t Val. Loss: 1.696 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 47\n",
      "\tTrain Loss: 0.090\n",
      "\t Val. Loss: 1.697 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 48\n",
      "\tTrain Loss: 0.076\n",
      "\t Val. Loss: 1.674 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 49\n",
      "\tTrain Loss: 0.072\n",
      "\t Val. Loss: 1.704 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 50\n",
      "\tTrain Loss: 0.079\n",
      "\t Val. Loss: 1.688 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 51\n",
      "\tTrain Loss: 0.096\n",
      "\t Val. Loss: 1.670 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 52\n",
      "\tTrain Loss: 0.076\n",
      "\t Val. Loss: 1.664 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 53\n",
      "\tTrain Loss: 0.065\n",
      "\t Val. Loss: 1.658 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 54\n",
      "\tTrain Loss: 0.063\n",
      "\t Val. Loss: 1.665 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 55\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.684 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 56\n",
      "\tTrain Loss: 0.079\n",
      "\t Val. Loss: 1.699 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 57\n",
      "\tTrain Loss: 0.069\n",
      "\t Val. Loss: 1.693 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 58\n",
      "\tTrain Loss: 0.061\n",
      "\t Val. Loss: 1.646 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 59\n",
      "\tTrain Loss: 0.050\n",
      "\t Val. Loss: 1.649 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 60\n",
      "\tTrain Loss: 0.050\n",
      "\t Val. Loss: 1.662 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 61\n",
      "\tTrain Loss: 0.060\n",
      "\t Val. Loss: 1.644 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 62\n",
      "\tTrain Loss: 0.062\n",
      "\t Val. Loss: 1.605 | Val. Acc: 57.45%\n",
      "--------------------------------------------------\n",
      "Epoch 63\n",
      "\tTrain Loss: 0.050\n",
      "\t Val. Loss: 1.593 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 64\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.608 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 65\n",
      "\tTrain Loss: 0.063\n",
      "\t Val. Loss: 1.611 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 66\n",
      "\tTrain Loss: 0.063\n",
      "\t Val. Loss: 1.615 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 67\n",
      "\tTrain Loss: 0.066\n",
      "\t Val. Loss: 1.632 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 68\n",
      "\tTrain Loss: 0.050\n",
      "\t Val. Loss: 1.625 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 69\n",
      "\tTrain Loss: 0.069\n",
      "\t Val. Loss: 1.629 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 70\n",
      "\tTrain Loss: 0.052\n",
      "\t Val. Loss: 1.645 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 71\n",
      "\tTrain Loss: 0.067\n",
      "\t Val. Loss: 1.619 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 72\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.625 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 73\n",
      "\tTrain Loss: 0.048\n",
      "\t Val. Loss: 1.635 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 74\n",
      "\tTrain Loss: 0.043\n",
      "\t Val. Loss: 1.640 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 75\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.633 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 76\n",
      "\tTrain Loss: 0.043\n",
      "\t Val. Loss: 1.649 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 77\n",
      "\tTrain Loss: 0.056\n",
      "\t Val. Loss: 1.665 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 78\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.674 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 79\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.676 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 80\n",
      "\tTrain Loss: 0.065\n",
      "\t Val. Loss: 1.671 | Val. Acc: 57.45%\n",
      "--------------------------------------------------\n",
      "Epoch 81\n",
      "\tTrain Loss: 0.066\n",
      "\t Val. Loss: 1.671 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 82\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.641 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 83\n",
      "\tTrain Loss: 0.062\n",
      "\t Val. Loss: 1.648 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 84\n",
      "\tTrain Loss: 0.057\n",
      "\t Val. Loss: 1.652 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 85\n",
      "\tTrain Loss: 0.047\n",
      "\t Val. Loss: 1.621 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 86\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.625 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 87\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.682 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 88\n",
      "\tTrain Loss: 0.053\n",
      "\t Val. Loss: 1.765 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 89\n",
      "\tTrain Loss: 0.036\n",
      "\t Val. Loss: 1.747 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 90\n",
      "\tTrain Loss: 0.067\n",
      "\t Val. Loss: 1.690 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 91\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.693 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 92\n",
      "\tTrain Loss: 0.056\n",
      "\t Val. Loss: 1.685 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 93\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.687 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 94\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.663 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 95\n",
      "\tTrain Loss: 0.062\n",
      "\t Val. Loss: 1.639 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 96\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.651 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 97\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.679 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 98\n",
      "\tTrain Loss: 0.054\n",
      "\t Val. Loss: 1.671 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 99\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.645 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 100\n",
      "\tTrain Loss: 0.052\n",
      "\t Val. Loss: 1.656 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 101\n",
      "\tTrain Loss: 0.043\n",
      "\t Val. Loss: 1.667 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 102\n",
      "\tTrain Loss: 0.041\n",
      "\t Val. Loss: 1.674 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 103\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.667 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 104\n",
      "\tTrain Loss: 0.050\n",
      "\t Val. Loss: 1.675 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 105\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.687 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 106\n",
      "\tTrain Loss: 0.054\n",
      "\t Val. Loss: 1.665 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 107\n",
      "\tTrain Loss: 0.074\n",
      "\t Val. Loss: 1.669 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 108\n",
      "\tTrain Loss: 0.048\n",
      "\t Val. Loss: 1.621 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 109\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.607 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 110\n",
      "\tTrain Loss: 0.049\n",
      "\t Val. Loss: 1.598 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 111\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.593 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 112\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.606 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 113\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.602 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 114\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.591 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 115\n",
      "\tTrain Loss: 0.055\n",
      "\t Val. Loss: 1.607 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 116\n",
      "\tTrain Loss: 0.034\n",
      "\t Val. Loss: 1.613 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 117\n",
      "\tTrain Loss: 0.060\n",
      "\t Val. Loss: 1.573 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 118\n",
      "\tTrain Loss: 0.075\n",
      "\t Val. Loss: 1.531 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 119\n",
      "\tTrain Loss: 0.071\n",
      "\t Val. Loss: 1.551 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 120\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.575 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 121\n",
      "\tTrain Loss: 0.055\n",
      "\t Val. Loss: 1.552 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 122\n",
      "\tTrain Loss: 0.053\n",
      "\t Val. Loss: 1.549 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 123\n",
      "\tTrain Loss: 0.047\n",
      "\t Val. Loss: 1.537 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 124\n",
      "\tTrain Loss: 0.056\n",
      "\t Val. Loss: 1.534 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 125\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.550 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 126\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.562 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 127\n",
      "\tTrain Loss: 0.064\n",
      "\t Val. Loss: 1.574 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 128\n",
      "\tTrain Loss: 0.067\n",
      "\t Val. Loss: 1.532 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 129\n",
      "\tTrain Loss: 0.032\n",
      "\t Val. Loss: 1.527 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 130\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.535 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 131\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.557 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 132\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.573 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 133\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.551 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 134\n",
      "\tTrain Loss: 0.041\n",
      "\t Val. Loss: 1.556 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 135\n",
      "\tTrain Loss: 0.060\n",
      "\t Val. Loss: 1.553 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 136\n",
      "\tTrain Loss: 0.032\n",
      "\t Val. Loss: 1.555 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 137\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.557 | Val. Acc: 57.45%\n",
      "--------------------------------------------------\n",
      "Epoch 138\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.550 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 139\n",
      "\tTrain Loss: 0.034\n",
      "\t Val. Loss: 1.570 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 140\n",
      "\tTrain Loss: 0.057\n",
      "\t Val. Loss: 1.564 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 141\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.551 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 142\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.530 | Val. Acc: 57.45%\n",
      "--------------------------------------------------\n",
      "Epoch 143\n",
      "\tTrain Loss: 0.057\n",
      "\t Val. Loss: 1.573 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 144\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.594 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 145\n",
      "\tTrain Loss: 0.047\n",
      "\t Val. Loss: 1.633 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 146\n",
      "\tTrain Loss: 0.054\n",
      "\t Val. Loss: 1.684 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 147\n",
      "\tTrain Loss: 0.052\n",
      "\t Val. Loss: 1.682 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 148\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.577 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 149\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.545 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 150\n",
      "\tTrain Loss: 0.052\n",
      "\t Val. Loss: 1.541 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 151\n",
      "\tTrain Loss: 0.047\n",
      "\t Val. Loss: 1.540 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 152\n",
      "\tTrain Loss: 0.043\n",
      "\t Val. Loss: 1.572 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 153\n",
      "\tTrain Loss: 0.041\n",
      "\t Val. Loss: 1.578 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 154\n",
      "\tTrain Loss: 0.048\n",
      "\t Val. Loss: 1.605 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 155\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.609 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 156\n",
      "\tTrain Loss: 0.032\n",
      "\t Val. Loss: 1.597 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 157\n",
      "\tTrain Loss: 0.036\n",
      "\t Val. Loss: 1.606 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 158\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.589 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 159\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.589 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 160\n",
      "\tTrain Loss: 0.050\n",
      "\t Val. Loss: 1.579 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 161\n",
      "\tTrain Loss: 0.035\n",
      "\t Val. Loss: 1.592 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 162\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.611 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 163\n",
      "\tTrain Loss: 0.051\n",
      "\t Val. Loss: 1.613 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 164\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.605 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 165\n",
      "\tTrain Loss: 0.036\n",
      "\t Val. Loss: 1.562 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 166\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.538 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 167\n",
      "\tTrain Loss: 0.054\n",
      "\t Val. Loss: 1.539 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 168\n",
      "\tTrain Loss: 0.050\n",
      "\t Val. Loss: 1.532 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 169\n",
      "\tTrain Loss: 0.043\n",
      "\t Val. Loss: 1.542 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 170\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.588 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 171\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.591 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 172\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.596 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 173\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.588 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 174\n",
      "\tTrain Loss: 0.033\n",
      "\t Val. Loss: 1.629 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 175\n",
      "\tTrain Loss: 0.041\n",
      "\t Val. Loss: 1.638 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 176\n",
      "\tTrain Loss: 0.041\n",
      "\t Val. Loss: 1.615 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 177\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.625 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 178\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.621 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 179\n",
      "\tTrain Loss: 0.030\n",
      "\t Val. Loss: 1.615 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 180\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.632 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 181\n",
      "\tTrain Loss: 0.030\n",
      "\t Val. Loss: 1.629 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 182\n",
      "\tTrain Loss: 0.033\n",
      "\t Val. Loss: 1.631 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 183\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.655 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 184\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.626 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 185\n",
      "\tTrain Loss: 0.043\n",
      "\t Val. Loss: 1.647 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 186\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.617 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 187\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.635 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 188\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.628 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 189\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.624 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 190\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.619 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 191\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.623 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 192\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.649 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 193\n",
      "\tTrain Loss: 0.043\n",
      "\t Val. Loss: 1.634 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 194\n",
      "\tTrain Loss: 0.032\n",
      "\t Val. Loss: 1.650 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 195\n",
      "\tTrain Loss: 0.035\n",
      "\t Val. Loss: 1.650 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 196\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.661 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 197\n",
      "\tTrain Loss: 0.033\n",
      "\t Val. Loss: 1.694 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 198\n",
      "\tTrain Loss: 0.031\n",
      "\t Val. Loss: 1.695 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 199\n",
      "\tTrain Loss: 0.030\n",
      "\t Val. Loss: 1.713 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 200\n",
      "\tTrain Loss: 0.035\n",
      "\t Val. Loss: 1.707 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Final Test Accuracy: 64.54%\n",
      "\n",
      "GCN模型分类报告：\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "    positive       0.76      0.85      0.81        75\n",
      "     neutral       0.67      0.71      0.69        34\n",
      "    negative       0.38      0.16      0.22        19\n",
      "\n",
      "    accuracy                           0.71       128\n",
      "   macro avg       0.60      0.57      0.57       128\n",
      "weighted avg       0.68      0.71      0.69       128\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnoAAAIgCAYAAAASv8SdAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABUWklEQVR4nO3deZxO9f//8ec1u2HMjD0zaOzLGEWTSYsloZClTws+SNYSlUiWFimDaj62UiqGSlIfLYiUPVEJw9jDkDU0ZoYx12zn94ef69v1GeW6cDkz53rcP7dzuznnOuc9r3N9jvHq9V6OzTAMQwAAALAcH7MDAAAAgGeQ6AEAAFgUiR4AAIBFkegBAABYFIkeAACARZHoAQAAWBSJHgAAgEWR6AEAAFgUiR4AAIBFkegBcElOTo6SkpKuqo1Tp0457e/cuVPbt293Onb+/Hk988wz2rp1a4Hr8/Ly9NRTT2nLli1XFcffWbp0qVavXq28vDyPtA8A15uf2QEAKBo++OADPfPMM5oxY4a6d++uqVOnavDgwfL19S1wrmEYqlGjhnbt2uU49umnn6pPnz5699131bVrV0nShx9+qP/85z9q3LixBg4cqIoVK6p///7y8fFRs2bNFBMT49RuUlKSpkyZoo4dOzodX7NmjVasWFEgjtzcXOXl5Sk+Pl6SNGXKFB06dMjx+Q033KBnn33WsR8fH6/Tp09fMskEgKKIih4AlwwYMEDDhw9Xz549NXnyZAUGBqpWrVrKzc0tsH3wwQcKDAx0ur5Dhw5q166dunXrphEjRkiSxo0bpxMnTuiee+7Rww8/rDvuuEM2m02LFy9Whw4dCsTw7bffKi4uTs2bN5d0ocKXlZWln376Sf/5z390+PBhp+3o0aM6duyY4/p58+Zp06ZNCgsL08yZM3X8+HH98ccfOn78uI4ePaqffvpJgwYNUnp6us6cOaM///xTx44d0/nz5z34zQKA51DRA+Cyl19+WZmZmQoKClJAQIByc3N1+PDhAuelpqbK39/f6VhQUJDmzp2r6OhotW3bVpJ08uRJzZgxQ1OmTFHfvn3VuXNnvf3226pWrZo6d+6skSNHOlX1Pv30UyUlJclmszmOtW3bVm3btlXZsmX1/vvv/2P8AQEBuuuuu/TMM89ozJgx6tKlix566CGtXr3acc6AAQM0YMAAp+sWLlyodu3auf5FAUAhQaIHwCXZ2dkKCAjQhAkTZLPZlJiYqH379qlSpUqXPL9Ro0YFjtlsNo0aNUqSNGzYME2dOlUdOnTQggULdOzYMTVo0EBfffWVkpKS9Nxzz2nz5s2ORO+nn37Szp079fPPP2vgwIFq3LixHnroIQUGBmrHjh0u3YOf34VfeT/88IMqV66shg0b6ssvv5TNZlOrVq3UqlUrR3zShS7onJwcBQUFufVdAUBhQdctgMs6cuSIIiMj1b17d8eEjJycHNWqVUuGYRTYZs2apdzcXMf1K1eu1D333OMY+3b+/Hn17dtXa9as0bvvvqsNGzaoR48eOnnypM6cOaMqVaro008/VZs2bfTnn39KkkaOHKlOnTopNjZWwcHBKl++vO68807deuutki504/5v1+3hw4cvObFi2bJljq7hsLAw/f7779q6dauefPJJ7dixQ7/88ouCgoJUrFgxlSxZUgEBAR79fgHAU6joAbisiIgIrV69Wg8++KDat2+v3bt3y263a/fu3U7dqH9Vu3Ztx5/LlCmj8+fPq2HDhho2bJgaN26sTp06yWazycfHR3l5efLx8dHNN9/s1EZeXp569uypWbNmaeTIkSpXrtzfxpiSknLJ6uLJkydVpkwZp2PLly/X0KFDHftjx45Vjx49VL58eY0ePVr79+/X8uXLXfpuAKAwI9ED4JI6depow4YN2rt3r4KDg9W/f389+uijf3u+j8//dRjUr19fa9eu1fTp0xUaGqr27dsrJydHfn5+eu211/TWW28pOTlZpUqVcmojLy/PUZGrX7++goODlZWVpfz8fKWnp+vgwYOOymG1atX022+/Oa5dtWqVWrRoofDw8AKxjRkzRs8++6zuv/9+zZ8/X5999pnWrFmj48ePKy8vT4Zh6Pjx48rOzlZ2draqV69+NV8dAJjGZhiGYXYQAIqezz//XD/99JNef/11x7GXX35ZERER6tu3r/Lz852SvUtZuHChOnfuLMMwHOPn/mr37t2qUqWKzpw5c8mETbpQbXz11Vf16quvFkj0WrZs6dSF3LJlS91xxx16+eWX1bp1azVq1Ei5ublO9yBdGMtXvHhx5eTkKCQkRMePH3fpOwGAwoYxegDcsmjRIhmGoUOHDjnWybPb7crJydGmTZt06NAhZWZmqkuXLpoyZYrTtcOGDdOBAwckXVhD78EHH1Rubq6Sk5OVlZXl2LZs2SK73e5YoqVkyZI6duyYcnJyZBiGypQpo2nTpikzM1Pr16+XdGHixNmzZx3b+fPnHdW5S2nXrp3mzZun559/Xtu2bdOZM2eUm5urgQMH6u6779aZM2d07tw5kjwARRpdtwBctnnzZnXq1ElbtmyRj4+PFi9e7KjEvf322/Lx8dGGDRtUv3591a1bV9HR0Y5rT5w4oYSEBNWqVUtr1qzRvHnzNGHCBA0ZMkR33nmn08LLF7trL7bt4+OjChUqSJL27dunU6dOafXq1RowYIBjXN7+/fsVEhJSIGa73V5g1uzMmTOVmJiosLAwBQQEqHbt2pesKF683jAMZt4CKJKo6AFw2dNPP62+ffuqXr16kqTOnTs7Fknu16+fJCkzM1MLFizQwoUL1aJFC8e1CxcuVEBAgB5++GGNHTtWGzdu1KBBgyRJa9eu1fHjxx3b2rVr/zaGxMREFStWTEuWLFH37t2Vn58v6cIYvUvNAL5UgrZhwwbVq1dPX3zxhUJCQuTv7y+bzSabzaa33npL3377rWM/KCiowLp6AFBUUNED4JKZM2cqKSlJ//3vfyXJ0SWan5+vb7/91lG9u/fee9WgQQNJ0kcffaTKlSvrrrvu0meffaYWLVooJCTEUXm7OH6uQYMGTrN3/667NSUlRdOmTVP37t3VtWtXtWrVSmFhYbrllltcuoecnBxJ0owZMxzH9u7dq8DAQMcCzyNHjlRKSormzp0rScrKylKxYsVcah8AChsSPQCXtWfPHj3zzDMaPXq0ypQpo/z8fC1evFi7d+9W5cqVFRQUpI8++kg2m01nzpyRdKH7dfz48Xr44YdVrlw5fffddwXG7F1M6JKSkpyWY9m1a5fq1KnjdO7x48fVvn17BQUF6bXXXlOZMmU0adIkPffccwoODnaso/dXeXl5ysjIUGRkpMLCwpwmZlz0vzNqg4ODFRAQ4OgqBoCijK5bAJdVrFgxtWnTRoMHD5Z0oTK2d+9eNWzYUJ988ol+++03xcXF6ZZbbtGkSZNUtmxZhYeH68yZM+rRo4fGjx8vwzAc76i96OJiyH+1evVq9enTR5IcCxVnZWXprrvuUkpKihYuXOhYF+/xxx/Xjh07FBkZqYyMDN10001O280336xbb71V69atc8R9Ofn5+crOzr7yLwsAChGWVwFwRU6fPq3SpUu7dG52drYSEhI0fPhwpy7abdu2KSYmRjt37nRU9NLT09WgQQM98sgjio+Pd5y7bt06ZWdnF0gWr7VevXpp165djtm8AFCUkegBAABYFF23AAAAFkWiBwAAYFEkegAAABZFogcAAGBRJHoAAAAWZakFk4vd/KTZIQBOfluZYHYIQAHBAb6XPwm4jsKDzXsmPZk7nN88zWNtu4qKHgAAgEVZqqIHAADgFpu1a17WvjsAAAAvRkUPAAB4r7+8ltGKSPQAAID3ousWAAAARREVPQAA4L0s3nVLRQ8AAMCiqOgBAADvxRg9AAAAFEVU9AAAgPdijB4AAACKIip6AADAe1l8jB6JHgAA8F503QIAAKAooqIHAAC8l8W7bq19dwAAAF6Mih4AAPBejNEDAABAUURFDwAAeC/G6AEAAKAooqIHAAC8l8XH6JHoAQAA70XXLQAAAIoiEj0AAOC9bD6e267A888/r/bt2zv2k5OTFRsbq/DwcA0bNkyGYbjVHokeAABAIZCcnKy3335bkyZNkiTZ7Xa1b99ejRo10saNG7Vjxw4lJia61SaJHgAA8F4+Ns9tbjAMQ/3799fTTz+tatWqSZKWLFmitLQ0JSQkqFq1aho3bpw++OAD927PrbMBAADgErvdrvT0dKfNbrdf8tz33ntPW7ZsUVRUlBYtWqScnBwlJSUpLi5OwcHBkqSYmBjt2LHDrRhI9AAAgPfy4Bi9+Ph4hYaGOm3x8fEFQjh79qxGjx6tGjVq6PDhw0pISNBdd92l9PR0RUVF/V+oNpt8fX2Vmprq8u2R6AEAAHjAiBEjlJaW5rSNGDGiwHkLFizQuXPntGLFCr3wwgtatmyZzpw5o5kzZyowMNDp3KCgIGVmZrocA+voAQAA7+XBBZMDAwMLJGqXcvjwYTVu3FilSpWSJPn5+SkmJkYpKSk6efKk07kZGRkKCAhwOQYqegAAwHsVguVVKlWqpPPnzzsdO3jwoN58801t2LDBcSwlJUV2u92RELqCRA8AAMBEbdu21c6dO/XOO+/o8OHDmjJlirZs2aJWrVopLS1Nc+bMkSSNHz9eLVu2lK+vr8tt03ULAAC8VyF4122pUqW0dOlSPfvssxoyZIgqVKigefPmqXr16poxY4a6du2qYcOGKS8vT6tXr3arbRI9AAAAk8XFxWndunUFjnfs2FF79+7Vxo0b1aRJE5UtW9atdkn0AACA97rCV5VdTxEREYqIiLiiawv/3QEAAOCKUNEDAADeqxCM0fMkKnoAAAAWRUUPAAB4ryIwRu9qkOgBAADvRdctAAAAiiIqegAAwHtZvOvW2ncHAADgxajoAQAA78UYPQAAABRFVPQAAID3YoweAAAAiiIqegAAwHtZvKJHogcAALwXkzEAAABQFJme6OXk5GjcuHFq3LixIiIitH37dt16663at2+f2aEBAACrs/l4bisETI/iiSee0H//+1/17t1bGRkZCg4OVlxcnPr37292aAAAAEWa6WP0Pv/8c23atElRUVEaPny4fH19NWTIENWvX9/s0AAAgNUxRs+zKlWqpDVr1jgd++233xQVFWVSRAAAANZgekVv4sSJ6tixo959911lZmZq6NChWrt2rWbPnm12aAAAwOoKyVg6TzE90WvTpo22b9+uefPm6aabblJkZKQmTJhARQ8AAOAqmZ7o5efnq1q1aho1apTZoQAAAG/DGD3PKleunHr37q1vvvlGOTk5ZocDAAC8iM1m89hWGJie6K1atUp16tRRQkKCIiMj9e9//1tffPGFsrKyzA4NAACgSDO96zY6OlrR0dEaOnSoMjMztWLFCn300Ufq3r27zp49a3Z4AADAwgpL5c1TTE/0Lvr111+1ZMkSffPNN0pLS9NTTz1ldkgAAABFmumJXo8ePbRs2TKVK1dODzzwgGbMmKHo6GizwwIAAN7A2gU98xO92rVra/To0apZs6bZoQAAAFiK6YneyJEjzQ4BAAB4KauP0TN91i0AAAA8w/SKHgAAgFmsXtEzJdGrWrWqtm7dqhIlSigqKupvv+T9+/df58gAAACsw5REb9asWQoODpYkJSYmmhECAAAAFT1PaNq06SX/DAAAcD1ZPdFjMgYkSWMH36/PJ/W/5GdfTXtC/27f+DpHBEhLF32pFo3rF9iWLvrS7NAASdLTA/tp0ddfmB0G8LeYjAHVrXaD+j14p+K6TCjw2SP33qJWt9fVZ9/+akJk8HZ3t26rO5q2cOyfz8xUvx4PKebmRiZGBVyw9JuF2vDjD2rZ+l6zQ8HVsHZBz/yK3sSJE5WTk+N0bMWKFWrWrJk5AXmhaaMf0bS5q3Tg8Cmn4+ElgxU/pLN2HzhuUmTwdv7+/ioRUtKxLVuyUHc2u1sVIyqZHRq8XFraGU1JmKgqN0aZHQrwj0xP9EaMGKHz5887Hatbt65+/vlnkyLyLo91vl0xtSKVcuS07r0zWn5+//dIjB/SWV+vTNLP21LMCxD4/7Ltdi2Y95G69uxjdiiApiRMVNPmLVWvfgOzQ8FVstlsHtsKA9O6btesWSNJMgxD69atU/HixR37S5cu5ZVo10HxYgF6aWA7/XbopCLKh6lr21gN79NarftOVuOYKDW/taYaPThObz73L7NDBbT8229UJzpGFSpGmB0KvNyvv/ykjT9v0NzPvtabE8eZHQ7wj0xL9Hr27CnpQiY9YMAA+fhcqCT5+PioRo0a+vDDD//xervdLrvd7nTMyM+TzcfXMwFbUIe7b1LxYgG6t98UpaZn6vWZy7Rx/kj1fuB2DXi4qQaP+1QZ57LMDhOQJH39xXw92vcJs8OAl7Pb7Rr/6st6buRLKl6ihNnh4BooLJU3TzEt0Ttw4ICkC4ndtm3bVLJkSbeuj4+P15gxY5yO+ZaPlf8Nt16zGK0uolyYftmWotT0TElSXl6+kvceUYUyofp1+0Et/WG7yRECFxz5/ZCOHj6kRrfGmR0KvNzM96arTr1o3X4nS4OhaDB91m3r1q3l7+/v9nUjRozQkCFDnI6Vu3P4tQrLKxw+kapiQQFOxyrfUEr/at1IZzPtOrZmoiQpOChAD9zTULdEV9HT8fPNCBVebtXybxV3e1P5+bn/uwK4lpYtWawzqX+q5Z0XlpzKyjqv5d8t1Y7kbXpu5IsmR4crQUXPw5YsWXJF1wUGBiowMNDpGN227lm6drsShj+oPv+6Q0vWJKvD3Q0UUytSd/dK0OETZxznjR/SST9vTdGHCzeYFyy82s/rf1Cbdh3NDgPQuzM/VG5enmN/asLrio6JUdv2nUyMCleDRA+WlZqeqQ4D39b4IZ00YUhnnTidrh7Pz9KPW5zfMXw2065TZ87q9JlzJkUKb2bPytKu7dv07IiXzA4FULnyFZz2iwUHKzQsXGHh4SZFBPwzm2EYhtlBXCvFbn7S7BAAJ7+tTDA7BKCA4AB6P1C4hAeb90yW7vmJx9o+PbuLx9p2lSkVvapVq2rr1q0qUaKEoqKi/rZsun///kseBwAAwOWZkujNmjVLwcHBkqTExEQzQgAAAGCMnic0bdr0kn8GAADAtcNkDAAA4LWsXtEz/V23AAAA8AzTE739+/erW7duMgxDGzduVExMjOrXr69169aZHRoAALA4m83msa0wML3rtmfPnoqOjpbNZtMzzzyjtm3bysfHR0888YSSkpLMDg8AAFhZ4cjHPMb0RG/Tpk369NNPdfbsWW3ZskUrV67UyZMnNWnSJLNDAwAAKNJMT/SqVKmiTz/9VFlZWbrtttvk5+enFStWqEqVKmaHBgAALK6wdLF6iumJ3qRJk9SzZ08FBwfrk08+0YoVK9SnTx99/PHHZocGAABQpJme6LVq1UrHjh1z7GdmZurkyZMqUaKEiVEBAABvQEXvOvn555/1+++/q3LlyoqNjTU7HAAAgCLP9ETvyJEj6tChg/bu3auKFSvq6NGjqlmzpr766itVrFjR7PAAAICFWb2iZ/o6ev3799ctt9yikydPaufOnTpx4oQaNmyovn37mh0aAABAkWZ6Re+HH37Qtm3bFBAQIEkKCgrSqFGjFBMTY3JkAADA6qjoeVj9+vU1e/Zsp2OzZ89WdHS0SREBAACvYfPgVgiYnuhNnz5d06dPV506dXTfffepdu3aeuedd/Tuu++aHRoAAMB1MWjQIKfXp1WvXl2SlJycrNjYWIWHh2vYsGEyDMOtdk1P9KKjo7Vnzx6NGjVKzZs310svvaQ9e/aoXr16ZocGAAAsrrC86/bXX3/V4sWLlZqaqtTUVG3evFl2u13t27dXo0aNtHHjRu3YsUOJiYlutWv6GL0TJ05owIABWrRokfLy8uTv76+OHTtq6tSpKleunNnhAQAAeFRubq6Sk5N11113Oa0j/OWXXyotLU0JCQkKDg7WuHHjNHDgQPXq1cvltk2v6PXq1UuGYeiXX37RiRMntG7dOmVlZbl1EwAAAFeiMFT0tm7dKsMwdNNNN6lYsWJq06aNDh06pKSkJMXFxSk4OFiSFBMTox07drh1f6ZX9H788UclJSU53m1btmxZTZ48WTfddJO5gQEAAFwFu90uu93udCwwMFCBgYFOx3bu3Kl69epp6tSpKlOmjAYPHqz+/furbt26ioqKcpxns9nk6+ur1NRUhYeHuxSD6RW9Zs2aaf78+U7HPvnkE7Vq1cqkiAAAgLfwZEUvPj5eoaGhTlt8fHyBGLp166YNGzYoNjZWUVFRmjZtmpYtW6b8/PwCSWFQUJAyMzNdvj/TK3rHjh3T8OHDNW3aNEVGRurQoUM6evSo4uLi1KJFC0nSihUrTI4SAADAPSNGjNCQIUOcjv1v4nYpYWFhys/PV4UKFZScnOz0WUZGhmPtYVeYnug98cQTZocAAAC8lQfXu7tUN+2lDBkyRHFxcXrooYckSb/88ot8fHxUv359vf/++47zUlJSZLfbVapUKZdjMD3R69mzp9khAAAAL1UY3oxx0003adSoUapQoYJyc3M1aNAgPfroo2rVqpXS0tI0Z84c9ejRQ+PHj1fLli3l6+vrctumJ3oAAADerEePHtq5c6c6dOigkJAQderUSePGjZOfn59mzJihrl27atiwYcrLy9Pq1avdattmuLvEciFW7OYnzQ4BcPLbygSzQwAKCA5wvRoAXA/hweY9k1UGL/RY2wentL8m7Rw5ckQbN25UkyZNVLZsWbeupaIHAABQiEVERCgiIuKKriXRAwAAXqswjNHzJNPX0QMAAIBnUNEDAABei4oeAAAAiiQqegAAwHtZu6BHogcAALwXXbcAAAAokqjoAQAAr0VFDwAAAEUSFT0AAOC1LF7Qo6IHAABgVVT0AACA12KMHgAAAIokKnoAAMBrWbygR6IHAAC8F123AAAAKJKo6AEAAK9l8YIeFT0AAACroqIHAAC8lo+PtUt6VPQAAAAsiooeAADwWozRAwAAQJFERQ8AAHgtq6+jR6IHAAC8lsXzPLpuAQAArIqKHgAA8FpW77qlogcAAGBRVPQAAIDXoqIHAACAIomKHgAA8FoWL+hR0QMAALAqKnoAAMBrWX2MHokeAADwWhbP8+i6BQAAsCoqegAAwGtZveuWih4AAIBFUdEDAABey+IFPSp6AAAAVkVFDwAAeC3G6AEAAKBIoqIHAAC8lsULelT0AAAArIqKHgAA8FpWH6NHogcAALyWxfM8ayV6O757w+wQACfLfzthdghAAQ/dVMnsEABcJ5ZK9AAAANxh9a5bJmMAAABYFBU9AADgtSxe0KOiBwAAYFVU9AAAgNdijB4AAACKJCp6AADAa1m8oEeiBwAAvBddtwAAACiSqOgBAACvRUUPAAAARRIVPQAA4LUsXtCjogcAAGBVVPQAAIDXYoweAAAAiiQqegAAwGtZvKBHogcAALwXXbcAAAC4btq0aaPExERJUnJysmJjYxUeHq5hw4bJMAy32iLRAwAAXstm89x2JT7++GN9++23kiS73a727durUaNG2rhxo3bs2OFI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ceJE5eXlKScnR0FBQU4x5eTkyMfHR76+vo5js2bN0lNPPaUlS5YoPDxcAQEBuvHGG1W7dm099dRTGjRokAzDUG5uboH35wJAUcU6egCuypEjRyRJKSkpuvXWW9WzZ0/Vq1dPkvTNN9/o9ddf18qVK52u6dWrl3r06KEFCxaoXbt26tKliyRp7969qlq1ql555RWlpqYqMDDQ8b7ki4KDgx0J3MqVK9W2bVuVKFFCNptN0oUk79y5c/r+++/VrFkzSdL+/fv13HPPqXLlymrdurXq1aun2267TVWqVNGJEyf06quvasSIEQoLC1Pr1q31wQcfeOz7AoDriUQPwFXJysrS2LFjtW/fPo0ZM8aR5EkX3s9cvXr1Atd06tRJjRs31g033KBixYppypQpOnTokDZs2KAffvhBy5Yt0w8//KDGjRs7rvnjjz+UlpamtLQ02e127dmzR7GxsZftDt6wYYMeeughPfHEExoyZIgqVqyoJUuW6OjRo2rZsqXWr1+vwMBA3XPPPfrtt9/k58evRQDWwW80AFdt27Zt+vHHHzVnzhxJF5KrPn366NSpU8rLy9P69eslSYMHD9a//vUvLVq0SD169HBcf+TIEd1yyy2aNm2aJMnX19ep21WSvv/+e61atUpffvmlqlSpooyMDPXt21dxcXGXjCkvL0++vr6qVq2aXnvtNXXv3l2StG/fPi1YsEDPPfecZs+erejoaEnSzJkz5ePDsGUA1sJvNQBXLC8vTzabTf/973/12GOPKTs7W9KFiQ9lypTR8ePHtWLFCv30009q166dMjIydPLkSb388st64oknHBM2goKCFBYW9o8/q2vXrnrnnXdkt9vVtm1bJSQkqH///goNDVWZMmUUGhqqkiVLqkyZMipZsqQqV64sSSpbtqwjycvMzNSbb76pMWPG6L333tPYsWP16quv6ty5c2rRogWJHgDL4bcagCu2efNmRUdHq27dupoyZYri4uJks9kc4/YkqVWrVtq3b5+kC5W6WrVqad26dQoODnYkVoZhqFixYpf9ecuXL1d6ero+/PBD9ezZU5s2bVJaWppOnTqlYcOG6YknntCpU6eUnp7uiMEwDCUlJemll15S9erVdeLECW3evFkPPPCA1q5dq8DAQMXGxmro0KFauXKlTp486YFvCgDMQaIH4Irdcsst2rt3rxYuXKjq1atrwYIFioqKUpUqVRznZGVlqVq1ak7X3XDDDRoyZIhsNpvy8/N16tQplS5dWpL+cTmVKVOmqFq1anrggQe0fv16rV69Wl9//bVTYrlnzx5HV7EkJSQk6LbbbtPhw4f1xBNPaN68eapRo4bKlCmjiIgIvfzyy4qKilLDhg01efJkPfroo2IxAgBWwRg9ANdMhQoV9PXXXysjI0OSlJaWpsDAQBUvXlyScxL30EMPqV+/fjp//rx+++03VaxYUZKUnZ19yfXzFi1apE2bNqlv376SpHnz5ummm25StWrVHGMDJWnBggWaMWOGkpOTFRwcrEGDBqlPnz4KDQ1Vdna2Ro8erYMHD2r//v1q3ry5JOndd9/VHXfcoa5du3ruywEAE1DRA3DNlCxZUtHR0Y6ZsBs3blRUVJTj86ysLElSUlKStm/frg4dOmjXrl1aunSpGjVqpFatWmnGjBnKzc11jPe7aMaMGXrvvfcca+Y1b95cK1asUIUKFdS2bVvHec8++6yCgoI0duxYSVJAQIBCQ0P1xx9/KDo6Wjk5OTpy5Iiee+45SRcmggwePFg5OTme+2IAwCQkegCuuZiYGL355puaMWOG2rRpowULFuipp55S//79JUnjxo3T4MGDFRoaqqCgIH322WcKCQnR7bffrrNnz+rBBx/UxIkTndpcsGCB7rvvPsd+bm6uXnrpJT3zzDOONfQkyd/fX6NGjdL06dOVlpbmOF6uXDlFR0friy++UOPGjbV7925lZGTo888/V4cOHQp0LwOAFZDoAbgqaWlpOnTokNP6c6GhoVqwYIE2b96swYMH68svv9TDDz+s7OxsLV26VAsXLtTgwYMlSUOHDlW7du00ePBg3XXXXerVq5fCwsJUsWJFRwVQkqP9nJwc5eXlKSsrS926ddMjjzyir776SmvXrnVM6Hj44YeVnJys0NBQSf/XZTxq1CjVrVtXvr6++v777xUYGKgPPvhAvXv3lnQheQQAK2GMHoCr8sYbb2j27NmOrtBff/1VvXv3Vvny5bVu3TqFh4drzpw5euedd3Tbbbdp9uzZGjlypEqXLq05c+bo+++/16+//irpwivPevbsqbS0NCUkJGj8+PGaMGGC08+z2+3KyclRiRIlNGLECEnShAkTFBYWpm7dukm6kBRGRkY6rgkICFCJEiUuuRhyVlaWunTpIrvdLrvdrlOnTl12qRcAKCp41y2Aayo/P18bNmxQkyZNCnz2+++/q1KlSo59wzB09OhRRUREFDj3+PHjstvtTjN4AQDuIdEDAACwKMboAQAAWBSJHgAAgEWR6AEAAFgUiR4AAIBFkegBAABYFIkeAACARZHoAQAAWBSJHgAAgEX9P2mLEe45aDOCAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "from torch_geometric.data import Data\n",
    "from torch_geometric.nn import GCNConv, global_mean_pool\n",
    "from torch_geometric.loader import DataLoader\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import jieba\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import classification_report, confusion_matrix\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from collections import Counter\n",
    "\n",
    "# 设置Matplotlib支持中文字体显示\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "plt.rcParams['axes.unicode_minus'] = False\n",
    "\n",
    "# 1. 数据预处理增强\n",
    "def preprocess_text(text):\n",
    "    with open('chinese_stopwords.txt', encoding='utf-8') as f:\n",
    "        stopwords = set(f.read().split())\n",
    "    \n",
    "    try:\n",
    "        text = str(text)\n",
    "        words = jieba.lcut(text)\n",
    "        return ' '.join([word for word in words \n",
    "                       if word not in stopwords \n",
    "                       and len(word) > 1\n",
    "                       and not word.isdigit()])\n",
    "    except:\n",
    "        return ''\n",
    "\n",
    "# 加载并清洗数据\n",
    "df = pd.read_csv('final_labeled_comments.csv')\n",
    "df = df.dropna(subset=['text', '最终情感标签'])\n",
    "df['processed_text'] = df['text'].astype(str).apply(preprocess_text)\n",
    "\n",
    "# 过滤空文本\n",
    "df = df[df['processed_text'] != '']\n",
    "\n",
    "# 标签编码\n",
    "label_map = {'positive': 0, 'neutral': 1, 'negative': 2}\n",
    "df['label'] = df['最终情感标签'].map(label_map)\n",
    "\n",
    "# 2. 创建词汇表\n",
    "texts = df['processed_text'].tolist()\n",
    "words = ' '.join(texts).split()\n",
    "word_counts = Counter(words)\n",
    "vocab = {'<PAD>': 0, '<UNK>': 1}\n",
    "vocab.update({word: i+2 for i, (word, _) in enumerate(word_counts.most_common(10000))})\n",
    "\n",
    "# 3. 创建图数据\n",
    "def create_graph_data(texts, labels, vocab, max_len=128):\n",
    "    data_list = []\n",
    "    for text, label in zip(texts, labels):\n",
    "        words = text.split()[:max_len]\n",
    "        if not words:  # 跳过空文本\n",
    "            continue\n",
    "        indices = [vocab.get(word, vocab['<UNK>']) for word in words]\n",
    "        \n",
    "        # 节点特征\n",
    "        x = torch.tensor(indices, dtype=torch.long).unsqueeze(1)\n",
    "        \n",
    "        # 边连接\n",
    "        num_nodes = len(indices)\n",
    "        if num_nodes < 2:\n",
    "            edge_index = torch.empty((2, 0), dtype=torch.long)\n",
    "        else:\n",
    "            edge_index = torch.tensor(\n",
    "                [[i, i+1] for i in range(num_nodes-1)] + \n",
    "                [[i+1, i] for i in range(num_nodes-1)],\n",
    "                dtype=torch.long\n",
    "            ).t().contiguous()\n",
    "        \n",
    "        data = Data(\n",
    "            x=x,\n",
    "            edge_index=edge_index,\n",
    "            y=torch.tensor([label], dtype=torch.long),\n",
    "            num_nodes=num_nodes\n",
    "        )\n",
    "        data_list.append(data)\n",
    "    return data_list\n",
    "\n",
    "# 划分数据集\n",
    "train_texts, val_texts, train_labels, val_labels = train_test_split(\n",
    "    df['processed_text'], df['label'], \n",
    "    test_size=0.2, \n",
    "    random_state=42, \n",
    "    stratify=df['label']\n",
    ")\n",
    "\n",
    "# 创建图数据集\n",
    "train_data = create_graph_data(train_texts.tolist(), train_labels.tolist(), vocab)\n",
    "val_data = create_graph_data(val_texts.tolist(), val_labels.tolist(), vocab)\n",
    "\n",
    "# 4. 定义GCN模型\n",
    "class GCN(nn.Module):\n",
    "    def __init__(self, vocab_size, embedding_dim=128, hidden_dim=256, output_dim=3):\n",
    "        super().__init__()\n",
    "        self.embedding = nn.Embedding(vocab_size, embedding_dim)\n",
    "        self.conv1 = GCNConv(embedding_dim, hidden_dim)\n",
    "        self.conv2 = GCNConv(hidden_dim, hidden_dim)\n",
    "        self.classifier = nn.Linear(hidden_dim, output_dim)\n",
    "    \n",
    "    def forward(self, x, edge_index, batch=None):\n",
    "        x = self.embedding(x.squeeze())\n",
    "        x = self.conv1(x, edge_index)\n",
    "        x = F.relu(x)\n",
    "        x = F.dropout(x, p=0.5, training=self.training)\n",
    "        x = self.conv2(x, edge_index)\n",
    "        x = global_mean_pool(x, batch)\n",
    "        x = self.classifier(x)\n",
    "        return F.log_softmax(x, dim=1)\n",
    "\n",
    "# 初始化模型\n",
    "VOCAB_SIZE = len(vocab)\n",
    "model = GCN(vocab_size=VOCAB_SIZE, \n",
    "           embedding_dim=128,\n",
    "           hidden_dim=256,\n",
    "           output_dim=3)\n",
    "\n",
    "# 5. 数据加载器（添加drop_last=True）\n",
    "BATCH_SIZE = 32\n",
    "train_loader = DataLoader(train_data, batch_size=BATCH_SIZE, shuffle=True, drop_last=True)\n",
    "val_loader = DataLoader(val_data, batch_size=BATCH_SIZE, drop_last=True)\n",
    "\n",
    "# 6. 训练配置\n",
    "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
    "model = model.to(device)\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)\n",
    "criterion = nn.NLLLoss()\n",
    "\n",
    "# 7. 训练函数\n",
    "def train():\n",
    "    model.train()\n",
    "    total_loss = 0\n",
    "    for batch in train_loader:\n",
    "        batch = batch.to(device)\n",
    "        optimizer.zero_grad()\n",
    "        out = model(batch.x, batch.edge_index, batch.batch)\n",
    "        loss = criterion(out, batch.y.squeeze().long())\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        total_loss += loss.item()\n",
    "    return total_loss / len(train_loader)\n",
    "\n",
    "# 8. 评估函数\n",
    "def evaluate(loader):\n",
    "    model.eval()\n",
    "    total_loss = 0\n",
    "    correct = 0\n",
    "    with torch.no_grad():\n",
    "        for batch in loader:\n",
    "            batch = batch.to(device)\n",
    "            out = model(batch.x, batch.edge_index, batch.batch)\n",
    "            loss = criterion(out, batch.y.squeeze().long())\n",
    "            total_loss += loss.item()\n",
    "            pred = out.argmax(dim=1)\n",
    "            correct += (pred == batch.y.squeeze().long()).sum().item()\n",
    "    return total_loss/len(loader), correct/len(loader.dataset)\n",
    "\n",
    "# 9. 训练循环\n",
    "N_EPOCHS = 200\n",
    "best_val_acc = 0\n",
    "for epoch in range(1, N_EPOCHS+1):\n",
    "    train_loss = train()\n",
    "    val_loss, val_acc = evaluate(val_loader)\n",
    "    \n",
    "    if val_acc > best_val_acc:\n",
    "        best_val_acc = val_acc\n",
    "        torch.save(model.state_dict(), 'best_gcn_model.pt')\n",
    "    \n",
    "    print(f'Epoch {epoch:02}')\n",
    "    print(f'\\tTrain Loss: {train_loss:.3f}')\n",
    "    print(f'\\t Val. Loss: {val_loss:.3f} | Val. Acc: {val_acc*100:.2f}%')\n",
    "    print('-'*50)\n",
    "\n",
    "# 10. 最终评估\n",
    "model.load_state_dict(torch.load('best_gcn_model.pt'))\n",
    "_, test_acc = evaluate(val_loader)\n",
    "print(f'Final Test Accuracy: {test_acc*100:.2f}%')\n",
    "\n",
    "# 生成分类报告\n",
    "all_preds = []\n",
    "all_labels = []\n",
    "model.eval()\n",
    "with torch.no_grad():\n",
    "    for batch in val_loader:\n",
    "        batch = batch.to(device)\n",
    "        out = model(batch.x, batch.edge_index, batch.batch)\n",
    "        preds = out.argmax(dim=1).cpu().numpy()\n",
    "        all_preds.extend(preds)\n",
    "        all_labels.extend(batch.y.squeeze().cpu().numpy())\n",
    "\n",
    "print(\"\\nGCN模型分类报告：\")\n",
    "print(classification_report(all_labels, all_preds, target_names=label_map.keys()))\n",
    "\n",
    "# 混淆矩阵可视化\n",
    "def plot_confusion_matrix(y_true, y_pred, classes,save_path='12confusion_matrix.png'):\n",
    "    cm = confusion_matrix(y_true, y_pred)\n",
    "    plt.figure(figsize=(8, 6))\n",
    "    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', \n",
    "                xticklabels=classes, yticklabels=classes)\n",
    "    plt.xlabel('预测标签')\n",
    "    plt.ylabel('真实标签')\n",
    "    plt.title('混淆矩阵')\n",
    "    plt.savefig(save_path)  # 保存图片plt.savefig(save_path)  # 保存图片\n",
    "    plt.show()\n",
    "\n",
    "plot_confusion_matrix(all_labels, all_preds, list(label_map.keys()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "672e7653-dfe7-41ad-a44e-157a1a30628d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Defaulting to user installation because normal site-packages is not writeableNote: you may need to restart the kernel to use updated packages.\n",
      "\n",
      "Requirement already satisfied: networkx in c:\\programdata\\anaconda3\\lib\\site-packages (3.2.1)\n"
     ]
    }
   ],
   "source": [
    "pip install networkx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "533d25be-1117-4131-922e-f2f34f34cf46",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 01\n",
      "\tTrain Loss: 0.971\n",
      "\t Val. Loss: 0.871 | Val. Acc: 54.61%\n",
      "--------------------------------------------------\n",
      "Epoch 02\n",
      "\tTrain Loss: 0.787\n",
      "\t Val. Loss: 0.790 | Val. Acc: 57.45%\n",
      "--------------------------------------------------\n",
      "Epoch 03\n",
      "\tTrain Loss: 0.705\n",
      "\t Val. Loss: 0.755 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 04\n",
      "\tTrain Loss: 0.593\n",
      "\t Val. Loss: 0.746 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 05\n",
      "\tTrain Loss: 0.528\n",
      "\t Val. Loss: 0.777 | Val. Acc: 53.90%\n",
      "--------------------------------------------------\n",
      "Epoch 06\n",
      "\tTrain Loss: 0.446\n",
      "\t Val. Loss: 0.776 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 07\n",
      "\tTrain Loss: 0.359\n",
      "\t Val. Loss: 0.802 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 08\n",
      "\tTrain Loss: 0.319\n",
      "\t Val. Loss: 0.867 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 09\n",
      "\tTrain Loss: 0.245\n",
      "\t Val. Loss: 0.901 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 10\n",
      "\tTrain Loss: 0.231\n",
      "\t Val. Loss: 0.985 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 11\n",
      "\tTrain Loss: 0.213\n",
      "\t Val. Loss: 1.014 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 12\n",
      "\tTrain Loss: 0.185\n",
      "\t Val. Loss: 1.085 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 13\n",
      "\tTrain Loss: 0.175\n",
      "\t Val. Loss: 1.142 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 14\n",
      "\tTrain Loss: 0.124\n",
      "\t Val. Loss: 1.203 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 15\n",
      "\tTrain Loss: 0.122\n",
      "\t Val. Loss: 1.316 | Val. Acc: 56.03%\n",
      "--------------------------------------------------\n",
      "Epoch 16\n",
      "\tTrain Loss: 0.126\n",
      "\t Val. Loss: 1.343 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 17\n",
      "\tTrain Loss: 0.116\n",
      "\t Val. Loss: 1.377 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 18\n",
      "\tTrain Loss: 0.115\n",
      "\t Val. Loss: 1.388 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 19\n",
      "\tTrain Loss: 0.091\n",
      "\t Val. Loss: 1.427 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 20\n",
      "\tTrain Loss: 0.082\n",
      "\t Val. Loss: 1.485 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 21\n",
      "\tTrain Loss: 0.092\n",
      "\t Val. Loss: 1.500 | Val. Acc: 56.74%\n",
      "--------------------------------------------------\n",
      "Epoch 22\n",
      "\tTrain Loss: 0.081\n",
      "\t Val. Loss: 1.536 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 23\n",
      "\tTrain Loss: 0.078\n",
      "\t Val. Loss: 1.538 | Val. Acc: 56.74%\n",
      "--------------------------------------------------\n",
      "Epoch 24\n",
      "\tTrain Loss: 0.117\n",
      "\t Val. Loss: 1.557 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 25\n",
      "\tTrain Loss: 0.071\n",
      "\t Val. Loss: 1.597 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 26\n",
      "\tTrain Loss: 0.107\n",
      "\t Val. Loss: 1.570 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 27\n",
      "\tTrain Loss: 0.091\n",
      "\t Val. Loss: 1.564 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 28\n",
      "\tTrain Loss: 0.077\n",
      "\t Val. Loss: 1.621 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 29\n",
      "\tTrain Loss: 0.098\n",
      "\t Val. Loss: 1.601 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 30\n",
      "\tTrain Loss: 0.077\n",
      "\t Val. Loss: 1.573 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 31\n",
      "\tTrain Loss: 0.101\n",
      "\t Val. Loss: 1.585 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 32\n",
      "\tTrain Loss: 0.058\n",
      "\t Val. Loss: 1.573 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 33\n",
      "\tTrain Loss: 0.058\n",
      "\t Val. Loss: 1.583 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 34\n",
      "\tTrain Loss: 0.060\n",
      "\t Val. Loss: 1.597 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 35\n",
      "\tTrain Loss: 0.072\n",
      "\t Val. Loss: 1.572 | Val. Acc: 55.32%\n",
      "--------------------------------------------------\n",
      "Epoch 36\n",
      "\tTrain Loss: 0.068\n",
      "\t Val. Loss: 1.550 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 37\n",
      "\tTrain Loss: 0.054\n",
      "\t Val. Loss: 1.536 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 38\n",
      "\tTrain Loss: 0.066\n",
      "\t Val. Loss: 1.574 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 39\n",
      "\tTrain Loss: 0.058\n",
      "\t Val. Loss: 1.594 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 40\n",
      "\tTrain Loss: 0.066\n",
      "\t Val. Loss: 1.610 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 41\n",
      "\tTrain Loss: 0.049\n",
      "\t Val. Loss: 1.587 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 42\n",
      "\tTrain Loss: 0.064\n",
      "\t Val. Loss: 1.584 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 43\n",
      "\tTrain Loss: 0.089\n",
      "\t Val. Loss: 1.553 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 44\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.520 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 45\n",
      "\tTrain Loss: 0.061\n",
      "\t Val. Loss: 1.555 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 46\n",
      "\tTrain Loss: 0.053\n",
      "\t Val. Loss: 1.555 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 47\n",
      "\tTrain Loss: 0.041\n",
      "\t Val. Loss: 1.571 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 48\n",
      "\tTrain Loss: 0.056\n",
      "\t Val. Loss: 1.604 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 49\n",
      "\tTrain Loss: 0.084\n",
      "\t Val. Loss: 1.607 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 50\n",
      "\tTrain Loss: 0.079\n",
      "\t Val. Loss: 1.608 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 51\n",
      "\tTrain Loss: 0.067\n",
      "\t Val. Loss: 1.579 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 52\n",
      "\tTrain Loss: 0.052\n",
      "\t Val. Loss: 1.587 | Val. Acc: 58.87%\n",
      "--------------------------------------------------\n",
      "Epoch 53\n",
      "\tTrain Loss: 0.047\n",
      "\t Val. Loss: 1.549 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 54\n",
      "\tTrain Loss: 0.047\n",
      "\t Val. Loss: 1.573 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 55\n",
      "\tTrain Loss: 0.054\n",
      "\t Val. Loss: 1.564 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 56\n",
      "\tTrain Loss: 0.055\n",
      "\t Val. Loss: 1.557 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 57\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.592 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 58\n",
      "\tTrain Loss: 0.066\n",
      "\t Val. Loss: 1.666 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 59\n",
      "\tTrain Loss: 0.063\n",
      "\t Val. Loss: 1.650 | Val. Acc: 58.16%\n",
      "--------------------------------------------------\n",
      "Epoch 60\n",
      "\tTrain Loss: 0.057\n",
      "\t Val. Loss: 1.647 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 61\n",
      "\tTrain Loss: 0.086\n",
      "\t Val. Loss: 1.642 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 62\n",
      "\tTrain Loss: 0.056\n",
      "\t Val. Loss: 1.635 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 63\n",
      "\tTrain Loss: 0.074\n",
      "\t Val. Loss: 1.583 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 64\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.566 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 65\n",
      "\tTrain Loss: 0.053\n",
      "\t Val. Loss: 1.585 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 66\n",
      "\tTrain Loss: 0.062\n",
      "\t Val. Loss: 1.601 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 67\n",
      "\tTrain Loss: 0.056\n",
      "\t Val. Loss: 1.624 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 68\n",
      "\tTrain Loss: 0.073\n",
      "\t Val. Loss: 1.650 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 69\n",
      "\tTrain Loss: 0.054\n",
      "\t Val. Loss: 1.620 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 70\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.629 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 71\n",
      "\tTrain Loss: 0.061\n",
      "\t Val. Loss: 1.642 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 72\n",
      "\tTrain Loss: 0.050\n",
      "\t Val. Loss: 1.635 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 73\n",
      "\tTrain Loss: 0.053\n",
      "\t Val. Loss: 1.611 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 74\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.606 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 75\n",
      "\tTrain Loss: 0.055\n",
      "\t Val. Loss: 1.599 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 76\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.603 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 77\n",
      "\tTrain Loss: 0.069\n",
      "\t Val. Loss: 1.607 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 78\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.596 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 79\n",
      "\tTrain Loss: 0.048\n",
      "\t Val. Loss: 1.599 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 80\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.608 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 81\n",
      "\tTrain Loss: 0.053\n",
      "\t Val. Loss: 1.597 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 82\n",
      "\tTrain Loss: 0.060\n",
      "\t Val. Loss: 1.571 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 83\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.561 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 84\n",
      "\tTrain Loss: 0.051\n",
      "\t Val. Loss: 1.558 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 85\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.559 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 86\n",
      "\tTrain Loss: 0.057\n",
      "\t Val. Loss: 1.565 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 87\n",
      "\tTrain Loss: 0.035\n",
      "\t Val. Loss: 1.576 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 88\n",
      "\tTrain Loss: 0.050\n",
      "\t Val. Loss: 1.566 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 89\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.559 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 90\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.561 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 91\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.568 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 92\n",
      "\tTrain Loss: 0.049\n",
      "\t Val. Loss: 1.573 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 93\n",
      "\tTrain Loss: 0.077\n",
      "\t Val. Loss: 1.558 | Val. Acc: 56.74%\n",
      "--------------------------------------------------\n",
      "Epoch 94\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.545 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 95\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.553 | Val. Acc: 59.57%\n",
      "--------------------------------------------------\n",
      "Epoch 96\n",
      "\tTrain Loss: 0.059\n",
      "\t Val. Loss: 1.553 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 97\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.543 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 98\n",
      "\tTrain Loss: 0.052\n",
      "\t Val. Loss: 1.531 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 99\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.530 | Val. Acc: 65.96%\n",
      "--------------------------------------------------\n",
      "Epoch 100\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.547 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 101\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.553 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 102\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.551 | Val. Acc: 65.96%\n",
      "--------------------------------------------------\n",
      "Epoch 103\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.549 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 104\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.559 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 105\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.572 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 106\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.601 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 107\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.594 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 108\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.583 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 109\n",
      "\tTrain Loss: 0.034\n",
      "\t Val. Loss: 1.586 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 110\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.594 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 111\n",
      "\tTrain Loss: 0.047\n",
      "\t Val. Loss: 1.580 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 112\n",
      "\tTrain Loss: 0.035\n",
      "\t Val. Loss: 1.577 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 113\n",
      "\tTrain Loss: 0.070\n",
      "\t Val. Loss: 1.563 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 114\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.545 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 115\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.562 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 116\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.633 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 117\n",
      "\tTrain Loss: 0.061\n",
      "\t Val. Loss: 1.612 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 118\n",
      "\tTrain Loss: 0.036\n",
      "\t Val. Loss: 1.588 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 119\n",
      "\tTrain Loss: 0.049\n",
      "\t Val. Loss: 1.599 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 120\n",
      "\tTrain Loss: 0.065\n",
      "\t Val. Loss: 1.574 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 121\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.594 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 122\n",
      "\tTrain Loss: 0.043\n",
      "\t Val. Loss: 1.593 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 123\n",
      "\tTrain Loss: 0.036\n",
      "\t Val. Loss: 1.607 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 124\n",
      "\tTrain Loss: 0.054\n",
      "\t Val. Loss: 1.615 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 125\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.605 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 126\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.611 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 127\n",
      "\tTrain Loss: 0.041\n",
      "\t Val. Loss: 1.621 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 128\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.598 | Val. Acc: 65.96%\n",
      "--------------------------------------------------\n",
      "Epoch 129\n",
      "\tTrain Loss: 0.049\n",
      "\t Val. Loss: 1.591 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 130\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.601 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 131\n",
      "\tTrain Loss: 0.035\n",
      "\t Val. Loss: 1.600 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 132\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.591 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 133\n",
      "\tTrain Loss: 0.056\n",
      "\t Val. Loss: 1.584 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 134\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.584 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 135\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.607 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 136\n",
      "\tTrain Loss: 0.054\n",
      "\t Val. Loss: 1.561 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 137\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.561 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 138\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.558 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 139\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.554 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 140\n",
      "\tTrain Loss: 0.052\n",
      "\t Val. Loss: 1.563 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 141\n",
      "\tTrain Loss: 0.051\n",
      "\t Val. Loss: 1.569 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 142\n",
      "\tTrain Loss: 0.035\n",
      "\t Val. Loss: 1.569 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 143\n",
      "\tTrain Loss: 0.048\n",
      "\t Val. Loss: 1.575 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 144\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.565 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 145\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.573 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 146\n",
      "\tTrain Loss: 0.047\n",
      "\t Val. Loss: 1.553 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 147\n",
      "\tTrain Loss: 0.043\n",
      "\t Val. Loss: 1.538 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 148\n",
      "\tTrain Loss: 0.063\n",
      "\t Val. Loss: 1.533 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 149\n",
      "\tTrain Loss: 0.035\n",
      "\t Val. Loss: 1.509 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 150\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.519 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 151\n",
      "\tTrain Loss: 0.034\n",
      "\t Val. Loss: 1.530 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 152\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.535 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 153\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.527 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 154\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.538 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 155\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.552 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 156\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.557 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 157\n",
      "\tTrain Loss: 0.048\n",
      "\t Val. Loss: 1.535 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 158\n",
      "\tTrain Loss: 0.033\n",
      "\t Val. Loss: 1.534 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 159\n",
      "\tTrain Loss: 0.041\n",
      "\t Val. Loss: 1.535 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 160\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.533 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 161\n",
      "\tTrain Loss: 0.032\n",
      "\t Val. Loss: 1.548 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 162\n",
      "\tTrain Loss: 0.035\n",
      "\t Val. Loss: 1.530 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 163\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.533 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 164\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.538 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 165\n",
      "\tTrain Loss: 0.047\n",
      "\t Val. Loss: 1.540 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Epoch 166\n",
      "\tTrain Loss: 0.032\n",
      "\t Val. Loss: 1.536 | Val. Acc: 61.70%\n",
      "--------------------------------------------------\n",
      "Epoch 167\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.552 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 168\n",
      "\tTrain Loss: 0.046\n",
      "\t Val. Loss: 1.557 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 169\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.567 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 170\n",
      "\tTrain Loss: 0.043\n",
      "\t Val. Loss: 1.537 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 171\n",
      "\tTrain Loss: 0.033\n",
      "\t Val. Loss: 1.534 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 172\n",
      "\tTrain Loss: 0.058\n",
      "\t Val. Loss: 1.528 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 173\n",
      "\tTrain Loss: 0.043\n",
      "\t Val. Loss: 1.535 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 174\n",
      "\tTrain Loss: 0.057\n",
      "\t Val. Loss: 1.531 | Val. Acc: 65.96%\n",
      "--------------------------------------------------\n",
      "Epoch 175\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.516 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 176\n",
      "\tTrain Loss: 0.055\n",
      "\t Val. Loss: 1.511 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 177\n",
      "\tTrain Loss: 0.059\n",
      "\t Val. Loss: 1.502 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 178\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.482 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 179\n",
      "\tTrain Loss: 0.050\n",
      "\t Val. Loss: 1.562 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 180\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.497 | Val. Acc: 66.67%\n",
      "--------------------------------------------------\n",
      "Epoch 181\n",
      "\tTrain Loss: 0.033\n",
      "\t Val. Loss: 1.551 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 182\n",
      "\tTrain Loss: 0.063\n",
      "\t Val. Loss: 1.538 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 183\n",
      "\tTrain Loss: 0.030\n",
      "\t Val. Loss: 1.572 | Val. Acc: 60.28%\n",
      "--------------------------------------------------\n",
      "Epoch 184\n",
      "\tTrain Loss: 0.034\n",
      "\t Val. Loss: 1.595 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 185\n",
      "\tTrain Loss: 0.044\n",
      "\t Val. Loss: 1.591 | Val. Acc: 60.99%\n",
      "--------------------------------------------------\n",
      "Epoch 186\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.595 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 187\n",
      "\tTrain Loss: 0.040\n",
      "\t Val. Loss: 1.570 | Val. Acc: 65.96%\n",
      "--------------------------------------------------\n",
      "Epoch 188\n",
      "\tTrain Loss: 0.041\n",
      "\t Val. Loss: 1.547 | Val. Acc: 63.83%\n",
      "--------------------------------------------------\n",
      "Epoch 189\n",
      "\tTrain Loss: 0.037\n",
      "\t Val. Loss: 1.575 | Val. Acc: 65.96%\n",
      "--------------------------------------------------\n",
      "Epoch 190\n",
      "\tTrain Loss: 0.029\n",
      "\t Val. Loss: 1.609 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 191\n",
      "\tTrain Loss: 0.042\n",
      "\t Val. Loss: 1.606 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 192\n",
      "\tTrain Loss: 0.045\n",
      "\t Val. Loss: 1.572 | Val. Acc: 63.12%\n",
      "--------------------------------------------------\n",
      "Epoch 193\n",
      "\tTrain Loss: 0.028\n",
      "\t Val. Loss: 1.657 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 194\n",
      "\tTrain Loss: 0.038\n",
      "\t Val. Loss: 1.685 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 195\n",
      "\tTrain Loss: 0.032\n",
      "\t Val. Loss: 1.692 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 196\n",
      "\tTrain Loss: 0.032\n",
      "\t Val. Loss: 1.688 | Val. Acc: 64.54%\n",
      "--------------------------------------------------\n",
      "Epoch 197\n",
      "\tTrain Loss: 0.039\n",
      "\t Val. Loss: 1.675 | Val. Acc: 65.25%\n",
      "--------------------------------------------------\n",
      "Epoch 198\n",
      "\tTrain Loss: 0.058\n",
      "\t Val. Loss: 1.667 | Val. Acc: 65.96%\n",
      "--------------------------------------------------\n",
      "Epoch 199\n",
      "\tTrain Loss: 0.033\n",
      "\t Val. Loss: 1.659 | Val. Acc: 65.96%\n",
      "--------------------------------------------------\n",
      "Epoch 200\n",
      "\tTrain Loss: 0.035\n",
      "\t Val. Loss: 1.669 | Val. Acc: 62.41%\n",
      "--------------------------------------------------\n",
      "Final Test Accuracy: 66.67%\n",
      "\n",
      "GCN模型分类报告：\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "    positive       0.75      0.91      0.82        75\n",
      "     neutral       0.81      0.65      0.72        34\n",
      "    negative       0.40      0.21      0.28        19\n",
      "\n",
      "    accuracy                           0.73       128\n",
      "   macro avg       0.65      0.59      0.61       128\n",
      "weighted avg       0.71      0.73      0.71       128\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnoAAAIgCAYAAAASv8SdAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABWPElEQVR4nO3deZyNdf/H8feZ3TBmxp4ZNPYYo9Jk0mJJuEOWVtxI1hZEqSx3JWVQzT2WUgpDm5ZbCRFlTYYUw1gijJ3QmBnGnNmu3x9+nbtzD3UOTtfMdV7PHtfj4frOdX3nc8597uPj810um2EYhgAAAGA5PmYHAAAAAM8g0QMAALAoEj0AAACLItEDAACwKBI9AAAAiyLRAwAAsCgSPQAAAIsi0QMAALAoEj0AAACLItED4JK8vDylpKRcUR+nTp1yOt+5c6e2b9/u1Hb+/HkNGzZMW7duLXJ/QUGBhg4dqi1btlxRHJeydOlSrV69WgUFBR7pHwD+bn5mBwCgZJg5c6aGDRumGTNmqGfPnpo6daqGDBkiX1/fItcahqE6depo165djraPP/5Y/fr109tvv63u3btLkt577z39+9//VtOmTfX444+ratWqGjhwoHx8fNSiRQvFxMQ49ZuSkqIpU6aoc+fOTu1r1qzRihUrisSRn5+vgoICxcfHS5KmTJmigwcPOn5+zTXX6KmnnnKcx8fH6/Tp0xdNMgGgJKKiB8AlgwYN0rPPPqvevXtr8uTJCgwMVL169ZSfn1/kmDlzpgIDA53u79Spkzp06KAePXpo5MiRkqTx48frxIkTuuuuu/Tggw/qtttuk81m0+LFi9WpU6ciMXz99deKi4tTy5YtJV2o8OXk5GjDhg3697//rcOHDzsdR48e1bFjxxz3z5s3Tz/99JPCwsI0a9YsHT9+XL/++quOHz+uo0ePasOGDRo8eLAyMzN15swZ/fbbbzp27JjOnz/vwXcWADyHih4Al7344ovKzs5WUFCQAgIClJ+fr8OHDxe5Lj09Xf7+/k5tQUFB+vDDDxUdHa327dtLkk6ePKkZM2ZoypQp6t+/v7p27ao333xTtWrVUteuXTVq1Cinqt7HH3+slJQU2Ww2R1v79u3Vvn17VaxYUe++++6fxh8QEKA77rhDw4YN09ixY9WtWzc98MADWr16teOaQYMGadCgQU73LVy4UB06dHD9jQKAYoJED4BLcnNzFRAQoIkTJ8pmsykpKUl79+5VtWrVLnp9kyZNirTZbDaNHj1akjRixAhNnTpVnTp10vz583Xs2DE1btxYCxYsUEpKip555hlt3rzZkeht2LBBO3fu1MaNG/X444+radOmeuCBBxQYGKgdO3a49Br8/C585X333XeqXr26brzxRn3xxRey2Wxq06aN2rRp44hPujAEnZeXp6CgILfeKwAoLhi6BfCXjhw5osjISPXs2dOxICMvL0/16tWTYRhFjtmzZys/P99x/8qVK3XXXXc55r6dP39e/fv315o1a/T2228rOTlZvXr10smTJ3XmzBnVqFFDH3/8sdq1a6fffvtNkjRq1Ch16dJFsbGxCg4OVuXKlXX77bfr5ptvlnRhGPd/h24PHz580YUVy5YtcwwNh4WF6dChQ9q6daueeOIJ7dixQz/88IOCgoJUqlQplS1bVgEBAR59fwHAU6joAfhLERERWr16te6//3517NhRP//8s+x2u37++WenYdQ/ql+/vuPPFSpU0Pnz53XjjTdqxIgRatq0qbp06SKbzSYfHx8VFBTIx8dHN9xwg1MfBQUF6t27t2bPnq1Ro0apUqVKl4wxLS3totXFkydPqkKFCk5t3377rZ5++mnH+bhx49SrVy9VrlxZY8aM0b59+/Ttt9+69N4AQHFGogfAJdddd52Sk5O1Z88eBQcHa+DAgXr44Ycveb2Pz38HDBo1aqS1a9dq+vTpCg0NVceOHZWXlyc/Pz+98soreuONN5Samqpy5co59VFQUOCoyDVq1EjBwcHKyclRYWGhMjMzdeDAAUflsFatWvrll18c965atUqtWrVSeHh4kdjGjh2rp556Svfcc48++eQTffrpp1qzZo2OHz+ugoICGYah48ePKzc3V7m5uapdu/aVvHUAYBqbYRiG2UEAKHk+++wzbdiwQa+++qqj7cUXX1RERIT69++vwsJCp2TvYhYuXKiuXbvKMAzH/Lk/+vnnn1WjRg2dOXPmogmbdKHa+PLLL+vll18ukui1bt3aaQi5devWuu222/Tiiy+qbdu2atKkifLz851eg3RhLl/p0qWVl5enkJAQHT9+3KX3BACKG+boAXDLokWLZBiGDh486Ngnz263Ky8vTz/99JMOHjyo7OxsdevWTVOmTHG6d8SIEdq/f7+kC3vo3X///crP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Tmeq13OztXDVVgX4++mJHi1VpUJZbf/lmB566h3l5xeaHTK8TKVKlTXp9US9NmmC/v36JN3S7DaNGz/J7LDgxSpXruJ0HhwcrLCwcIXxxBYUUzbDMAyzg7haSt3whNkhAE5Ob5hqdghAEQWFlvnah0WEBJk3HaN874881vfpOd081rerTKno1axZU1u3blWZMmUUFRV1ybLpvn37/ubIAAAArMOURG/27NkKDg6WJCUlJZkRAgAAAHP0PKF58+YX/TMAAACuHhZjAAAAr2X1ih6bUQEAAFiU6Ynevn371KNHDxmGoU2bNikmJkaNGjXSunXrzA4NAABYnM1m89hRHJg+dNu7d29FR0fLZrNp2LBhat++vXx8fPTYY48pJSXF7PAAAICVFY98zGNMT/R++uknffzxxzp79qy2bNmilStX6uTJk0pMTDQ7NAAAgBLN9ESvRo0a+vjjj5WTk6NbbrlFfn5+WrFihWrUqGF2aAAAwOKKyxCrp5ie6CUmJqp3794KDg7WRx99pBUrVqhfv3764IMPzA4NAACgRDM90WvTpo2OHTvmOM/OztbJkydVpkwZE6MCAADegIre32Tjxo06dOiQqlevrtjYWLPDAQAAKPFMT/SOHDmiTp06ac+ePapataqOHj2qunXrasGCBapatarZ4QEAAAuzekXP9H30Bg4cqJtuukknT57Uzp07deLECd14443q37+/2aEBAACUaKZX9L777jtt27ZNAQEBkqSgoCCNHj1aMTExJkcGAACsjoqehzVq1Ehz5sxxapszZ46io6NNiggAAHgNmwePYsD0it706dPVtm1bffDBB4qKitK+ffuUlZWlZcuWmR0aAABAiWZ6ohcdHa3du3fr888/17Fjx9SzZ0/dc889Kl26tNmhAQAAi7P60K3pid6JEyc0aNAgLVq0SAUFBfL391fnzp01depUVapUyezwAAAASizT5+j16dNHhmHohx9+0IkTJ7Ru3Trl5OSoT58+ZocGAAAszmazeewoDkyv6H3//fdKSUlxPNu2YsWKmjx5sq6//npzAwMAACjhTK/otWjRQp988olT20cffaQ2bdqYFBEAAPAWVPQ87NixY3r22Wc1bdo0RUZG6uDBgzp69Kji4uLUqlUrSdKKFStMjhIAAKDkMT3Re+yxx8wOAQAAeKviUXjzGNMTvd69e5sdAgAA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0NatW3XXXXdJko4cOaKffvpJYWFhkqT8/HyVKVPGY3HAHOHh4WrcuLEkOeYlHT9+XCdPnlR4eLgkqbCwUFlZWcrJySlyf3Z2tlu/b9CgQfL393dqMwxDzz33nD7//HM1aNBAoaGhKigouJyXgxLK3c9h+fLlFRYWpvXr1ysyMlIZGRmqXbu2JOn8+fPq16+fVq9erRtuuEF+fn5X/Hny9/dXhw4d9PXXX+uWW26Rr6+voqOjJV34rly5cqXjuzI3N9dpWBdwF4leCXLw4EEVFhbKx8dHBw8elJ+fnyIjI7V//37HNTk5OTp69KiqV6+uc+fO6dy5c1q+fLlyc3P1/PPP65FHHtG2bdtc+n0+Pj5uzw259957NWDAAN1www266667HM+BjIyM1D333KPXXntNklRQUOD2X+oo/i62QCc/P1833XSTY+6SYRjKyMiQv7+/bDab01+amzZtKnL/n30OS5cuXaTtww8/1OrVq3X48GGVKVNGb775pj755JPLfUkogdz9HBYWFqpJkya6++67lZ+frwkTJqhixYqSpMmTJ+vkyZM6ceKEAgIC9Mwzz+jXX3916ttms13Wd+WHH36ojIwM3XvvvY72yMhIDRo0SE8++aQkKS8vT4WFhW71DfwRizFKkKNHjyo+Pl779+/XSy+9pE6dOqlTp07KysrS2LFjdeDAAQ0dOlR16tRRbGysCgsL1b59e73//vs6deqUfHx83PrCqF27tpYuXapjx47p22+/demeRo0aKSMjQ++//77Tl1e3bt20du1a7dmzR9KFL88+ffq49wagRGrfvr0OHDigjRs3ytfXV/PmzVO7du1kGIYiIyO1fft2paen68SJE45/CPyRu5/Ds2fPSpJ+++03LVmyROPGjWMyO/70c7h27Vr99ttv2rRpkw4ePKhhw4Y57jt79qwMw9CpU6f04Ycfavr06UU+T7Vr19bixYt15MgRrVmzxqV42rRpow0bNmjRokVO35W9evXSggULdPz4ceXn52v06NEaPXr01XkT4J1MGjKGm2bPnm3ExcUZ9957r1G2bFmjbdu2xrFjxwzDMIytW7cazZo1M0JCQox27doZhw4dctz36aefGvXr1zeCgoKM6OhoY/Xq1U79/tlcpZSUFCMmJsYIDAw0br/9dpfvGzlypFGqVCnj3LlzTu1LliwxoqOjjeDgYKNly5bG7t273XwXUJxd7DOh/5+7tHHjRuPmm282goODjdjYWGPDhg2GYRhGQUGB0a1bNyMiIsKIjY01FixYUGSO3qU+h82bNzdmz55dJI6MjAyjTZs2RnBwsNG0aVPjhRdeMCpVqmScP3/+T2OFNVzO5zArK8uIjIw0ypUrZ9hsNiMkJMQYO3asYRiGcfDgQSMuLs4oXbq00bp1a2Po0KFGTEyMU//ffvutUatWLSMoKMjo3r27088uNkfvd926dbvo5zApKcmoXbu2UaZMGaNTp07GiRMnLu/NAAzDsBkG/9QtCZKSkpSUlMTGsQBwlf3rX//S4cOH9corryggIEDLly/XE088odOnT5sdGnDFmKMHAPBqnTt31uOPP666desqPz9fdevW1VtvvWV2WMBVQUUPAADAoliMAQAAYFEkegAAABZFogcAAGBRJHoAAAAWRaIH4Kqz2+1FHhNlGIbsdrtb/RiGcdWeCpCfn6/Vq1cX6e/nn3/WuXPnrsrvAIDihlW3AK5IRESEQkJCFBQUpIyMDN1///06cuSINm/erNzcXB05ckT16tVTYWGhcnNztWPHDnXu3Fn9+/dXx44dtXr1aqcnDVSuXFnXXXedJCkxMVEbNmzQRx995Pj5mDFjlJubq0mTJqmgoEB5eXkKCgpyiikvL08+Pj7y9fV1tM2ePVtDhw7VkiVLFB4eroCAAF177bWqX7++hg4dqsGDB8swDOXn5xd5fi4AlFTsowfgihw5ckSSlJaWpptvvlm9e/dWw4YNJUlfffWVXn31Va1cudLpnj59+qhXr16aP3++OnTooG7dukmS9uzZo5o1a+qll15Senq6AgMDHc9L/l1wcLAjgVu5cqXat2+vMmXKyGazSbqQ5J07d07ffPONWrRoIUnat2+fnnnmGVWvXl1t27ZVw4YNdcstt6hGjRo6ceKEXn75ZY0cOVJhYWFq27atZs6c6bH3CwD+TiR6AK5ITk6Oxo0bp71792rs2LGOJE+68Hzm2rVrF7mnS5cuatq0qa655hqVKlVKU6ZM0cGDB5WcnKzvvvtOy5Yt03fffaemTZs67vn111+VkZGhjIwM2e127d69W7GxsX85HJycnKwHHnhAjz32mIYPH66qVatqyZIlOnr0qFq3bq3169crMDBQd911l3755Rf5+fG1CMA6+EYDcMW2bdum77//XnPnzpV0Ibnq16+fTp06pYKCAq1fv16SNGTIEN13331atGiRevXq5bj/yJEjuummmzRt2jRJkq+vr9OwqyR98803WrVqlb744gvVqFFDWVlZ6t+/v+Li4i4aU0FBgXx9fVWrVi298sor6tmzpyRp7969mj9/vp555hnNmTNH0dHRkqRZs2bJx4dpywCshW81AJetoKBANptN//nPf/TII48oNzdX0oWFDxUqVNDx48e1YsUKbdiwQR06dFBWVpZOnjypF198UY899phjwUZQUJDCwsL+9Hd1795db731lux2u9q3b6+EhAQNHDhQoaGhqlChgkJDQ1W2bFlVqFBBZcuWVfXq1SVJFStWdCR52dnZev311zV27Fi98847GjdunF5++WWdO3dOrVq1ItEDYDl8qwG4bJs3b1Z0dLQaNGigKVOmKC4uTjabzTFvT5LatGmjvXv3SrpQqatXr57WrVun4OBgR2JlGIZKlSr1l7/v22+/VWZmpt577z317t1bP/30kzIyMnTq1CmNGDFCjz32mE6dOqXMzExHDIZhKCUlRS+88IJq166tEydOaPPmzbr33nu1du1aBQYGKjY2Vk8//bRWrlypkydPeuCdAgBzkOgBuGw33XST9uzZo4ULF6p27dqaP3++oqKiVKNGDcc1OTk5qlWrltN911xzjYYPHy6bzabCwkKdOnVK5cuXl6Q/3U5lypQpqlWrlu69916tX79eq1ev1pdffumUWO7evdsxVCxJCQkJuuWWW3T48GE99thjmjdvnurUqaMKFSooIiJCL774oqKionTjjTdq8uTJevjhh8VmBACsgjl6AK6aKlWq6Msvv1RWVpYkKSMjQ4GBgSpdurQk5yTugQce0IABA3T+/Hn98ssvqlq1qiQpNzf3ovvnLVq0SD/99JP69+8vSZo3b56uv/561apVyzE3UJLmz5+vGTNmKDU1VcHBwRo8eLD69eun0NBQ5ebmasyYMTpw4ID27dunli1bSpLefvtt3Xbbberevbvn3hwAMAEVPQBXTdmyZRUdHe1YCbtp0yZFRUU5fp6TkyNJSklJ0fbt29WpUyft2rVLS5cuVZMmTdSmTRvNmDFD+fn5jvl+v5sxY4beeecdx555LVu21IoVK1SlShW1b9/ecd1TTz2loKAgjRs3TpIUEBCg0NBQ/frrr4qOjlZeXp6OHDmiZ555RtKFhSBDhgxRXl6e594YADAJiR6Aqy4mJkavv/66ZsyYoXbt2mn+/PkaOnSoBg4cKEkaP368hgwZotDQUAUFBenTTz9VSEiIbr31Vp09e1b333+/Jk2a5NTn/PnzdffddzvO8/Pz9cILL2jYsGGOPfQkyd/fX6NHj9b06dOVkZHhaK9UqZKio6P1+eefq2nTpvr555+VlZWlzz77TJ06dSoyvAwAVkCiB+CKZGRk6ODBg077z4WGhmr+/PnavHmzhgwZoi+++EIPPvigcnNztXTpUi1cuFBDhgyRJD399NPq0KGDhgwZojvuuEN9+vRRWFiYqlat6qgASnL0n5eXp4KCAuXk5KhHjx566KGHtGDBAq1du9axoOPBBx9UamqqQkNDJf13yHj06NFq0KCBfH199c033ygwMFAzZ85U3759JV1IHgHASpijB+CKvPbaa5ozZ45jKPTHH39U3759VblyZa1bt07h4eGaO3eu3nrrLd1yyy2aM2eORo0apfLly2vu3Ln65ptv9OOPP0q68Miz3r17KyMjQwkJCZowYYImTpzo9Pvsdrvy8vJUpkwZjRw5UpI0ceJEhYWFqUePHpIuJIWRkZGOewICAlSmTJmLboack5Ojbt26yW63y26369SpU3+51QsAlBQ86xbAVVVYWKjk5GQ1a9asyM8OHTqkatWqOc4Nw9DRo0cVERFR5Nrjx4/Lbrc7reAFALiHRA8AAMCimKMHAABgUSR6AAAAFkWiBwAAYFEkegAAABZFogcAAGBRJHoAAAAWRaIHAABgUSR6AAAAFvV/5/oZYtGLiRMAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "ename": "TypeError",
     "evalue": "GCN.forward() got an unexpected keyword argument 'return_attention'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[27], line 239\u001b[0m\n\u001b[0;32m    236\u001b[0m         plt\u001b[38;5;241m.\u001b[39mshow()\n\u001b[0;32m    238\u001b[0m \u001b[38;5;66;03m# 注意：这里的return_attention参数是示意性的，具体实现需要修改模型的前向函数以返回中间层特征。\u001b[39;00m\n\u001b[1;32m--> 239\u001b[0m visualize_propagation(model, val_loader, vocab)\n",
      "Cell \u001b[1;32mIn[27], line 221\u001b[0m, in \u001b[0;36mvisualize_propagation\u001b[1;34m(model, loader, vocab, num_graphs, save_path)\u001b[0m\n\u001b[0;32m    219\u001b[0m     \u001b[38;5;28;01mbreak\u001b[39;00m\n\u001b[0;32m    220\u001b[0m batch \u001b[38;5;241m=\u001b[39m batch\u001b[38;5;241m.\u001b[39mto(device)\n\u001b[1;32m--> 221\u001b[0m out, (h_1, h_2) \u001b[38;5;241m=\u001b[39m model(batch\u001b[38;5;241m.\u001b[39mx, batch\u001b[38;5;241m.\u001b[39medge_index, return_attention\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)  \u001b[38;5;66;03m# 修改为获取中间层输出\u001b[39;00m\n\u001b[0;32m    223\u001b[0m \u001b[38;5;66;03m# 这里假设模型有返回中间层特征的能力，具体实现需根据模型调整\u001b[39;00m\n\u001b[0;32m    224\u001b[0m h \u001b[38;5;241m=\u001b[39m h_1 \u001b[38;5;241m+\u001b[39m h_2  \u001b[38;5;66;03m# 示意性合并\u001b[39;00m\n",
      "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python312\\site-packages\\torch\\nn\\modules\\module.py:1739\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m   1737\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_compiled_call_impl(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)  \u001b[38;5;66;03m# type: ignore[misc]\u001b[39;00m\n\u001b[0;32m   1738\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1739\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call_impl(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
      "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python312\\site-packages\\torch\\nn\\modules\\module.py:1750\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m   1745\u001b[0m \u001b[38;5;66;03m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[0;32m   1746\u001b[0m \u001b[38;5;66;03m# this function, and just call forward.\u001b[39;00m\n\u001b[0;32m   1747\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_pre_hooks\n\u001b[0;32m   1748\u001b[0m         \u001b[38;5;129;01mor\u001b[39;00m _global_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_backward_hooks\n\u001b[0;32m   1749\u001b[0m         \u001b[38;5;129;01mor\u001b[39;00m _global_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[1;32m-> 1750\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m forward_call(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m   1752\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m   1753\u001b[0m called_always_called_hooks \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mset\u001b[39m()\n",
      "\u001b[1;31mTypeError\u001b[0m: GCN.forward() got an unexpected keyword argument 'return_attention'"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "from torch_geometric.data import Data\n",
    "from torch_geometric.nn import GCNConv, global_mean_pool\n",
    "from torch_geometric.loader import DataLoader\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import jieba\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import classification_report, confusion_matrix\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from collections import Counter\n",
    "\n",
    "# 设置Matplotlib支持中文字体显示\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "plt.rcParams['axes.unicode_minus'] = False\n",
    "\n",
    "# 1. 数据预处理增强\n",
    "def preprocess_text(text):\n",
    "    with open('chinese_stopwords.txt', encoding='utf-8') as f:\n",
    "        stopwords = set(f.read().split())\n",
    "    \n",
    "    try:\n",
    "        text = str(text)\n",
    "        words = jieba.lcut(text)\n",
    "        return ' '.join([word for word in words \n",
    "                       if word not in stopwords \n",
    "                       and len(word) > 1\n",
    "                       and not word.isdigit()])\n",
    "    except:\n",
    "        return ''\n",
    "\n",
    "# 加载并清洗数据\n",
    "df = pd.read_csv('final_labeled_comments.csv')\n",
    "df = df.dropna(subset=['text', '最终情感标签'])\n",
    "df['processed_text'] = df['text'].astype(str).apply(preprocess_text)\n",
    "\n",
    "# 过滤空文本\n",
    "df = df[df['processed_text'] != '']\n",
    "\n",
    "# 标签编码\n",
    "label_map = {'positive': 0, 'neutral': 1, 'negative': 2}\n",
    "df['label'] = df['最终情感标签'].map(label_map)\n",
    "\n",
    "# 2. 创建词汇表\n",
    "texts = df['processed_text'].tolist()\n",
    "words = ' '.join(texts).split()\n",
    "word_counts = Counter(words)\n",
    "vocab = {'<PAD>': 0, '<UNK>': 1}\n",
    "vocab.update({word: i+2 for i, (word, _) in enumerate(word_counts.most_common(10000))})\n",
    "\n",
    "# 3. 创建图数据\n",
    "def create_graph_data(texts, labels, vocab, max_len=128):\n",
    "    data_list = []\n",
    "    for text, label in zip(texts, labels):\n",
    "        words = text.split()[:max_len]\n",
    "        if not words:  # 跳过空文本\n",
    "            continue\n",
    "        indices = [vocab.get(word, vocab['<UNK>']) for word in words]\n",
    "        \n",
    "        # 节点特征\n",
    "        x = torch.tensor(indices, dtype=torch.long).unsqueeze(1)\n",
    "        \n",
    "        # 边连接\n",
    "        num_nodes = len(indices)\n",
    "        if num_nodes < 2:\n",
    "            edge_index = torch.empty((2, 0), dtype=torch.long)\n",
    "        else:\n",
    "            edge_index = torch.tensor(\n",
    "                [[i, i+1] for i in range(num_nodes-1)] + \n",
    "                [[i+1, i] for i in range(num_nodes-1)],\n",
    "                dtype=torch.long\n",
    "            ).t().contiguous()\n",
    "        \n",
    "        data = Data(\n",
    "            x=x,\n",
    "            edge_index=edge_index,\n",
    "            y=torch.tensor([label], dtype=torch.long),\n",
    "            num_nodes=num_nodes\n",
    "        )\n",
    "        data_list.append(data)\n",
    "    return data_list\n",
    "\n",
    "# 划分数据集\n",
    "train_texts, val_texts, train_labels, val_labels = train_test_split(\n",
    "    df['processed_text'], df['label'], \n",
    "    test_size=0.2, \n",
    "    random_state=42, \n",
    "    stratify=df['label']\n",
    ")\n",
    "\n",
    "# 创建图数据集\n",
    "train_data = create_graph_data(train_texts.tolist(), train_labels.tolist(), vocab)\n",
    "val_data = create_graph_data(val_texts.tolist(), val_labels.tolist(), vocab)\n",
    "\n",
    "# 4. 定义GCN模型\n",
    "class GCN(nn.Module):\n",
    "    def __init__(self, vocab_size, embedding_dim=128, hidden_dim=256, output_dim=3):\n",
    "        super().__init__()\n",
    "        self.embedding = nn.Embedding(vocab_size, embedding_dim)\n",
    "        self.conv1 = GCNConv(embedding_dim, hidden_dim)\n",
    "        self.conv2 = GCNConv(hidden_dim, hidden_dim)\n",
    "        self.classifier = nn.Linear(hidden_dim, output_dim)\n",
    "    \n",
    "    def forward(self, x, edge_index, batch=None):\n",
    "        x = self.embedding(x.squeeze())\n",
    "        x = self.conv1(x, edge_index)\n",
    "        x = F.relu(x)\n",
    "        x = F.dropout(x, p=0.5, training=self.training)\n",
    "        x = self.conv2(x, edge_index)\n",
    "        x = global_mean_pool(x, batch)\n",
    "        x = self.classifier(x)\n",
    "        return F.log_softmax(x, dim=1)\n",
    "\n",
    "# 初始化模型\n",
    "VOCAB_SIZE = len(vocab)\n",
    "model = GCN(vocab_size=VOCAB_SIZE, \n",
    "           embedding_dim=128,\n",
    "           hidden_dim=256,\n",
    "           output_dim=3)\n",
    "\n",
    "# 5. 数据加载器（添加drop_last=True）\n",
    "BATCH_SIZE = 32\n",
    "train_loader = DataLoader(train_data, batch_size=BATCH_SIZE, shuffle=True, drop_last=True)\n",
    "val_loader = DataLoader(val_data, batch_size=BATCH_SIZE, drop_last=True)\n",
    "\n",
    "# 6. 训练配置\n",
    "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
    "model = model.to(device)\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)\n",
    "criterion = nn.NLLLoss()\n",
    "\n",
    "# 7. 训练函数\n",
    "def train():\n",
    "    model.train()\n",
    "    total_loss = 0\n",
    "    for batch in train_loader:\n",
    "        batch = batch.to(device)\n",
    "        optimizer.zero_grad()\n",
    "        out = model(batch.x, batch.edge_index, batch.batch)\n",
    "        loss = criterion(out, batch.y.squeeze().long())\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        total_loss += loss.item()\n",
    "    return total_loss / len(train_loader)\n",
    "\n",
    "# 8. 评估函数\n",
    "def evaluate(loader):\n",
    "    model.eval()\n",
    "    total_loss = 0\n",
    "    correct = 0\n",
    "    with torch.no_grad():\n",
    "        for batch in loader:\n",
    "            batch = batch.to(device)\n",
    "            out = model(batch.x, batch.edge_index, batch.batch)\n",
    "            loss = criterion(out, batch.y.squeeze().long())\n",
    "            total_loss += loss.item()\n",
    "            pred = out.argmax(dim=1)\n",
    "            correct += (pred == batch.y.squeeze().long()).sum().item()\n",
    "    return total_loss/len(loader), correct/len(loader.dataset)\n",
    "\n",
    "# 9. 训练循环\n",
    "N_EPOCHS = 200\n",
    "best_val_acc = 0\n",
    "for epoch in range(1, N_EPOCHS+1):\n",
    "    train_loss = train()\n",
    "    val_loss, val_acc = evaluate(val_loader)\n",
    "    \n",
    "    if val_acc > best_val_acc:\n",
    "        best_val_acc = val_acc\n",
    "        torch.save(model.state_dict(), 'best_gcn_model.pt')\n",
    "    \n",
    "    print(f'Epoch {epoch:02}')\n",
    "    print(f'\\tTrain Loss: {train_loss:.3f}')\n",
    "    print(f'\\t Val. Loss: {val_loss:.3f} | Val. Acc: {val_acc*100:.2f}%')\n",
    "    print('-'*50)\n",
    "\n",
    "# 10. 最终评估\n",
    "model.load_state_dict(torch.load('best_gcn_model.pt'))\n",
    "_, test_acc = evaluate(val_loader)\n",
    "print(f'Final Test Accuracy: {test_acc*100:.2f}%')\n",
    "\n",
    "# 生成分类报告\n",
    "all_preds = []\n",
    "all_labels = []\n",
    "model.eval()\n",
    "with torch.no_grad():\n",
    "    for batch in val_loader:\n",
    "        batch = batch.to(device)\n",
    "        out = model(batch.x, batch.edge_index, batch.batch)\n",
    "        preds = out.argmax(dim=1).cpu().numpy()\n",
    "        all_preds.extend(preds)\n",
    "        all_labels.extend(batch.y.squeeze().cpu().numpy())\n",
    "\n",
    "print(\"\\nGCN模型分类报告：\")\n",
    "print(classification_report(all_labels, all_preds, target_names=label_map.keys()))\n",
    "\n",
    "# 混淆矩阵可视化\n",
    "def plot_confusion_matrix(y_true, y_pred, classes, save_path='confusion_matrix.png'):\n",
    "    cm = confusion_matrix(y_true, y_pred)\n",
    "    plt.figure(figsize=(8, 6))\n",
    "    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', \n",
    "                xticklabels=classes, yticklabels=classes)\n",
    "    plt.xlabel('预测标签')\n",
    "    plt.ylabel('真实标签')\n",
    "    plt.title('混淆矩阵')\n",
    "    plt.savefig(save_path)\n",
    "    plt.show()\n",
    "\n",
    "plot_confusion_matrix(all_labels, all_preds, list(label_map.keys()))\n",
    "\n",
    "# 传播路径可视化\n",
    "def visualize_propagation(model, loader, vocab, num_graphs=3,save_path='传播路径图'):\n",
    "    model.eval()\n",
    "    for i, batch in enumerate(loader):\n",
    "        if i >= num_graphs:\n",
    "            break\n",
    "        batch = batch.to(device)\n",
    "        out, (h_1, h_2) = model(batch.x, batch.edge_index, return_attention=True)  # 修改为获取中间层输出\n",
    "        \n",
    "        # 这里假设模型有返回中间层特征的能力，具体实现需根据模型调整\n",
    "        h = h_1 + h_2  # 示意性合并\n",
    "\n",
    "        # 可视化每个节点的特征\n",
    "        x = batch.x.cpu().numpy()\n",
    "        h = h.cpu().numpy()\n",
    "        plt.figure(figsize=(10, 4))\n",
    "        plt.imshow(h[0], cmap='viridis', aspect='auto')\n",
    "        plt.title(f'Graph {i+1} Feature Propagation')\n",
    "        plt.xlabel('Node Index')\n",
    "        plt.ylabel('Feature Dimension')\n",
    "        plt.colorbar()\n",
    "        plt.savefig(save_path)\n",
    "        plt.show()\n",
    "\n",
    "# 注意：这里的return_attention参数是示意性的，具体实现需要修改模型的前向函数以返回中间层特征。\n",
    "visualize_propagation(model, val_loader, vocab)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "529dcac3-22d0-495d-8d4d-55b0e72dd2f8",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
